@aiscene/core 9.0.6 → 9.0.8
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.mjs +24 -11
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/cache-config.mjs +19 -0
- package/dist/es/agent/cache-config.mjs.map +1 -0
- package/dist/es/agent/file-chooser.mjs +82 -0
- package/dist/es/agent/file-chooser.mjs.map +1 -0
- package/dist/es/agent/insight.mjs +101 -0
- package/dist/es/agent/insight.mjs.map +1 -0
- package/dist/es/agent/metrics.mjs +81 -0
- package/dist/es/agent/metrics.mjs.map +1 -0
- package/dist/es/agent/progress/ai-act-progress.mjs +199 -0
- package/dist/es/agent/progress/ai-act-progress.mjs.map +1 -0
- package/dist/es/agent/progress/index.mjs +2 -0
- package/dist/es/agent/progress/progress-bus.mjs +52 -0
- package/dist/es/agent/progress/progress-bus.mjs.map +1 -0
- package/dist/es/agent/prompt-context.mjs +25 -0
- package/dist/es/agent/prompt-context.mjs.map +1 -0
- package/dist/es/agent/record-to-report.mjs +14 -0
- package/dist/es/agent/record-to-report.mjs.map +1 -0
- package/dist/es/agent/run-gherkin-scenario.mjs +114 -0
- package/dist/es/agent/run-gherkin-scenario.mjs.map +1 -0
- package/dist/es/agent/run-markdown.mjs +62 -0
- package/dist/es/agent/run-markdown.mjs.map +1 -0
- package/dist/es/agent/screenshot-preparation.mjs +37 -0
- package/dist/es/agent/screenshot-preparation.mjs.map +1 -0
- package/dist/es/agent/ui-observer.mjs +385 -0
- package/dist/es/agent/ui-observer.mjs.map +1 -0
- package/dist/es/agent/utils.mjs +42 -4
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/ai-model/connectivity/fixture.mjs +8 -0
- package/dist/es/ai-model/connectivity/fixture.mjs.map +1 -0
- package/dist/es/ai-model/connectivity/index.mjs +2 -0
- package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +160 -0
- package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -0
- package/dist/es/ai-model/conversation-history.mjs.map +1 -1
- package/dist/es/ai-model/index.mjs +2 -1
- package/dist/es/ai-model/inspect.mjs +1 -1
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/model-adapter/chat-completion.mjs +69 -0
- package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/custom-planning-action.mjs +6 -0
- package/dist/es/ai-model/model-adapter/custom-planning-action.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/custom-planning-types.mjs +0 -0
- package/dist/es/ai-model/model-adapter/default-insight-protocol.mjs +28 -0
- package/dist/es/ai-model/model-adapter/default-insight-protocol.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs +145 -0
- package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/default-planning-protocol.mjs +124 -0
- package/dist/es/ai-model/model-adapter/default-planning-protocol.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/image-preprocess.mjs +27 -0
- package/dist/es/ai-model/model-adapter/image-preprocess.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/index.mjs +2 -0
- package/dist/es/ai-model/model-adapter/insight-protocol.mjs +0 -0
- package/dist/es/ai-model/model-adapter/insight.mjs +13 -0
- package/dist/es/ai-model/model-adapter/insight.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/locate-protocol.mjs +0 -0
- package/dist/es/ai-model/model-adapter/locate.mjs +53 -0
- package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/planning-protocol.mjs +0 -0
- package/dist/es/ai-model/model-adapter/planning.mjs +49 -0
- package/dist/es/ai-model/model-adapter/planning.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/resolve.mjs +54 -0
- package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/types.mjs +0 -0
- package/dist/es/ai-model/models/auto-glm/actions.mjs +205 -0
- package/dist/es/ai-model/models/auto-glm/actions.mjs.map +1 -0
- package/dist/es/ai-model/models/auto-glm/adapter.mjs +45 -0
- package/dist/es/ai-model/models/auto-glm/adapter.mjs.map +1 -0
- package/dist/es/ai-model/models/auto-glm/locate.mjs +11 -0
- package/dist/es/ai-model/models/auto-glm/locate.mjs.map +1 -0
- package/dist/es/ai-model/models/auto-glm/parser.mjs +217 -0
- package/dist/es/ai-model/models/auto-glm/parser.mjs.map +1 -0
- package/dist/es/ai-model/models/auto-glm/planning.mjs +33 -0
- package/dist/es/ai-model/models/auto-glm/planning.mjs.map +1 -0
- package/dist/es/ai-model/models/auto-glm/prompt.mjs +214 -0
- package/dist/es/ai-model/models/auto-glm/prompt.mjs.map +1 -0
- package/dist/es/ai-model/models/deepseek/adapter.mjs +79 -0
- package/dist/es/ai-model/models/deepseek/adapter.mjs.map +1 -0
- package/dist/es/ai-model/models/deepseek/locate-protocol.mjs +89 -0
- package/dist/es/ai-model/models/deepseek/locate-protocol.mjs.map +1 -0
- package/dist/es/ai-model/models/default.mjs +13 -0
- package/dist/es/ai-model/models/default.mjs.map +1 -0
- package/dist/es/ai-model/models/doubao.mjs +95 -0
- package/dist/es/ai-model/models/doubao.mjs.map +1 -0
- package/dist/es/ai-model/models/gemini.mjs +100 -0
- package/dist/es/ai-model/models/gemini.mjs.map +1 -0
- package/dist/es/ai-model/models/glm.mjs +46 -0
- package/dist/es/ai-model/models/glm.mjs.map +1 -0
- package/dist/es/ai-model/models/gpt.mjs +43 -0
- package/dist/es/ai-model/models/gpt.mjs.map +1 -0
- package/dist/es/ai-model/models/index.mjs +2 -0
- package/dist/es/ai-model/models/kimi.mjs +102 -0
- package/dist/es/ai-model/models/kimi.mjs.map +1 -0
- package/dist/es/ai-model/models/mimo.mjs +36 -0
- package/dist/es/ai-model/models/mimo.mjs.map +1 -0
- package/dist/es/ai-model/models/qwen.mjs +139 -0
- package/dist/es/ai-model/models/qwen.mjs.map +1 -0
- package/dist/es/ai-model/models/registry.mjs +51 -0
- package/dist/es/ai-model/models/registry.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/actions.mjs +147 -0
- package/dist/es/ai-model/models/ui-tars/actions.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/adapter.mjs +102 -0
- package/dist/es/ai-model/models/ui-tars/adapter.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/parser.mjs +40 -0
- package/dist/es/ai-model/models/ui-tars/parser.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/planning.mjs +25 -0
- package/dist/es/ai-model/models/ui-tars/planning.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/prompt.mjs +36 -0
- package/dist/es/ai-model/models/ui-tars/prompt.mjs.map +1 -0
- package/dist/es/ai-model/models/utils/intent.mjs +6 -0
- package/dist/es/ai-model/models/utils/intent.mjs.map +1 -0
- package/dist/es/ai-model/prompt/insight/index.mjs +3 -0
- package/dist/es/ai-model/prompt/insight/system-prompt.mjs +104 -0
- package/dist/es/ai-model/prompt/insight/system-prompt.mjs.map +1 -0
- package/dist/es/ai-model/prompt/insight/user-prompt.mjs +23 -0
- package/dist/es/ai-model/prompt/insight/user-prompt.mjs.map +1 -0
- package/dist/es/ai-model/prompt/locate/element-system-prompt.mjs +12 -0
- package/dist/es/ai-model/prompt/locate/element-system-prompt.mjs.map +1 -0
- package/dist/es/ai-model/prompt/locate/grounding-rules.mjs +13 -0
- package/dist/es/ai-model/prompt/locate/grounding-rules.mjs.map +1 -0
- package/dist/es/ai-model/prompt/locate/index.mjs +4 -0
- package/dist/es/ai-model/prompt/locate/search-area-system-prompt.mjs +9 -0
- package/dist/es/ai-model/prompt/locate/search-area-system-prompt.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/action-output-example.mjs +52 -0
- package/dist/es/ai-model/prompt/planning/action-output-example.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/action-space-description.mjs +28 -0
- package/dist/es/ai-model/prompt/planning/action-space-description.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/index.mjs +6 -0
- package/dist/es/ai-model/prompt/planning/multi-turn-example.mjs +221 -0
- package/dist/es/ai-model/prompt/planning/multi-turn-example.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/planning-response-example.mjs +25 -0
- package/dist/es/ai-model/prompt/planning/planning-response-example.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/sub-goals-text.mjs +17 -0
- package/dist/es/ai-model/prompt/planning/sub-goals-text.mjs.map +1 -0
- package/dist/es/ai-model/prompt/planning/system-prompt.mjs +293 -0
- package/dist/es/ai-model/prompt/planning/system-prompt.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/codex-app-server.mjs +1 -0
- package/dist/es/ai-model/service-caller/codex-app-server.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/index.mjs +35 -16
- package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/model-call-recorder.mjs +74 -0
- package/dist/es/ai-model/service-caller/model-call-recorder.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/openai-error.mjs +147 -0
- package/dist/es/ai-model/service-caller/openai-error.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/proxy-deps.node.mjs +9 -0
- package/dist/es/ai-model/service-caller/proxy-deps.node.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/proxy-deps.stub.mjs +12 -0
- package/dist/es/ai-model/service-caller/proxy-deps.stub.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/semantic-retry.mjs +33 -0
- package/dist/es/ai-model/service-caller/semantic-retry.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/types.mjs +0 -0
- package/dist/es/ai-model/shared/action-schema.mjs +15 -0
- package/dist/es/ai-model/shared/action-schema.mjs.map +1 -0
- package/dist/es/ai-model/shared/json.mjs +63 -0
- package/dist/es/ai-model/shared/json.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/bbox.mjs +60 -0
- package/dist/es/ai-model/shared/model-locate-result/bbox.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs +10 -0
- package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/errors.mjs +9 -0
- package/dist/es/ai-model/shared/model-locate-result/errors.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/factory.mjs +39 -0
- package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/index.mjs +6 -0
- package/dist/es/ai-model/shared/model-locate-result/parse.mjs +45 -0
- package/dist/es/ai-model/shared/model-locate-result/parse.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs +67 -0
- package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs +110 -0
- package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/types.mjs +9 -0
- package/dist/es/ai-model/shared/model-locate-result/types.mjs.map +1 -0
- package/dist/es/ai-model/shared/multimodal-prompt.mjs +55 -0
- package/dist/es/ai-model/shared/multimodal-prompt.mjs.map +1 -0
- package/dist/es/ai-model/shared/xml.mjs +42 -0
- package/dist/es/ai-model/shared/xml.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/index.mjs +4 -0
- package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs +23 -0
- package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/locate.mjs +168 -0
- package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +97 -0
- package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs +18 -0
- package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/search-area.mjs +55 -0
- package/dist/es/ai-model/workflows/grounding/search-area.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs +146 -0
- package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -0
- package/dist/es/ai-model/workflows/grounding/types.mjs +0 -0
- package/dist/es/ai-model/workflows/grounding/utils.mjs +50 -0
- package/dist/es/ai-model/workflows/grounding/utils.mjs.map +1 -0
- package/dist/es/ai-model/workflows/insight/extraction.mjs +101 -0
- package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -0
- package/dist/es/ai-model/workflows/insight/index.mjs +3 -0
- package/dist/es/ai-model/workflows/insight/insight-response-parser.mjs +26 -0
- package/dist/es/ai-model/workflows/insight/insight-response-parser.mjs.map +1 -0
- package/dist/es/ai-model/workflows/insight/order-sensitive.mjs +29 -0
- package/dist/es/ai-model/workflows/insight/order-sensitive.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/conversation-history.mjs +185 -0
- package/dist/es/ai-model/workflows/planning/conversation-history.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs +129 -0
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/index.mjs +4 -0
- package/dist/es/ai-model/workflows/planning/locate-normalization.mjs +41 -0
- package/dist/es/ai-model/workflows/planning/locate-normalization.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/planning-action-log.mjs +22 -0
- package/dist/es/ai-model/workflows/planning/planning-action-log.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/standard-planning-parser.mjs +99 -0
- package/dist/es/ai-model/workflows/planning/standard-planning-parser.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs +219 -0
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/types.mjs +0 -0
- package/dist/es/ai-model/workflows/recorder-generation/common.mjs +171 -0
- package/dist/es/ai-model/workflows/recorder-generation/common.mjs.map +1 -0
- package/dist/es/ai-model/workflows/recorder-generation/index.mjs +5 -0
- package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs +253 -0
- package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs.map +1 -0
- package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs +83 -0
- package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs.map +1 -0
- package/dist/es/ai-model/workflows/recorder-generation/playwright.mjs +123 -0
- package/dist/es/ai-model/workflows/recorder-generation/playwright.mjs.map +1 -0
- package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs +162 -0
- package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs.map +1 -0
- package/dist/es/common.mjs +12 -1
- package/dist/es/common.mjs.map +1 -1
- package/dist/es/constants.mjs +4 -0
- package/dist/es/constants.mjs.map +1 -0
- package/dist/es/device/index.mjs.map +1 -1
- package/dist/es/device/input-strategy.mjs +34 -0
- package/dist/es/device/input-strategy.mjs.map +1 -0
- package/dist/es/dump/html-utils.mjs +16 -1
- package/dist/es/dump/html-utils.mjs.map +1 -1
- package/dist/es/dump/image-reference.mjs +63 -0
- package/dist/es/dump/image-reference.mjs.map +1 -0
- package/dist/es/dump/report-action-dump.mjs +244 -0
- package/dist/es/dump/report-action-dump.mjs.map +1 -0
- package/dist/es/dump/report-dump-compactor.mjs +200 -0
- package/dist/es/dump/report-dump-compactor.mjs.map +1 -0
- package/dist/es/dump/screenshot-store.mjs +124 -37
- package/dist/es/dump/screenshot-store.mjs.map +1 -1
- package/dist/es/dump/task-service-dump.mjs +17 -0
- package/dist/es/dump/task-service-dump.mjs.map +1 -0
- package/dist/es/dump/task-status.mjs +18 -0
- package/dist/es/dump/task-status.mjs.map +1 -0
- package/dist/es/element-describer.mjs +198 -0
- package/dist/es/element-describer.mjs.map +1 -0
- package/dist/es/errors.mjs +20 -0
- package/dist/es/errors.mjs.map +1 -0
- package/dist/es/report-html-template.mjs +4 -0
- package/dist/es/report-html-template.mjs.map +1 -0
- package/dist/es/report-stats.mjs +113 -0
- package/dist/es/report-stats.mjs.map +1 -0
- package/dist/es/screenshot-item.mjs +7 -2
- package/dist/es/screenshot-item.mjs.map +1 -1
- package/dist/es/service/index.mjs +10 -5
- package/dist/es/service/index.mjs.map +1 -1
- package/dist/es/task-runner.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/es/yaml/cleanup.mjs +13 -0
- package/dist/es/yaml/cleanup.mjs.map +1 -0
- package/dist/lib/agent/agent.js +24 -11
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/cache-config.js +53 -0
- package/dist/lib/agent/cache-config.js.map +1 -0
- package/dist/lib/agent/file-chooser.js +125 -0
- package/dist/lib/agent/file-chooser.js.map +1 -0
- package/dist/lib/agent/insight.js +135 -0
- package/dist/lib/agent/insight.js.map +1 -0
- package/dist/lib/agent/metrics.js +115 -0
- package/dist/lib/agent/metrics.js.map +1 -0
- package/dist/lib/agent/progress/ai-act-progress.js +239 -0
- package/dist/lib/agent/progress/ai-act-progress.js.map +1 -0
- package/dist/lib/agent/progress/index.js +67 -0
- package/dist/lib/agent/progress/index.js.map +1 -0
- package/dist/lib/agent/progress/progress-bus.js +86 -0
- package/dist/lib/agent/progress/progress-bus.js.map +1 -0
- package/dist/lib/agent/prompt-context.js +62 -0
- package/dist/lib/agent/prompt-context.js.map +1 -0
- package/dist/lib/agent/record-to-report.js +48 -0
- package/dist/lib/agent/record-to-report.js.map +1 -0
- package/dist/lib/agent/run-gherkin-scenario.js +151 -0
- package/dist/lib/agent/run-gherkin-scenario.js.map +1 -0
- package/dist/lib/agent/run-markdown.js +96 -0
- package/dist/lib/agent/run-markdown.js.map +1 -0
- package/dist/lib/agent/screenshot-preparation.js +74 -0
- package/dist/lib/agent/screenshot-preparation.js.map +1 -0
- package/dist/lib/agent/ui-observer.js +425 -0
- package/dist/lib/agent/ui-observer.js.map +1 -0
- package/dist/lib/agent/utils.js +46 -2
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/ai-model/connectivity/fixture.js +45 -0
- package/dist/lib/ai-model/connectivity/fixture.js.map +1 -0
- package/dist/lib/ai-model/connectivity/index.js +38 -0
- package/dist/lib/ai-model/connectivity/index.js.map +1 -0
- package/dist/lib/ai-model/connectivity/run-connectivity-test.js +204 -0
- package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -0
- package/dist/lib/ai-model/conversation-history.js.map +1 -1
- package/dist/lib/ai-model/index.js +15 -11
- package/dist/lib/ai-model/inspect.js +1 -1
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/model-adapter/chat-completion.js +103 -0
- package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-action.js +40 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-action.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-types.js +20 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-types.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/default-insight-protocol.js +62 -0
- package/dist/lib/ai-model/model-adapter/default-insight-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/default-locate-protocol.js +182 -0
- package/dist/lib/ai-model/model-adapter/default-locate-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/default-planning-protocol.js +170 -0
- package/dist/lib/ai-model/model-adapter/default-planning-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/image-preprocess.js +61 -0
- package/dist/lib/ai-model/model-adapter/image-preprocess.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/index.js +38 -0
- package/dist/lib/ai-model/model-adapter/index.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/insight-protocol.js +20 -0
- package/dist/lib/ai-model/model-adapter/insight-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/insight.js +50 -0
- package/dist/lib/ai-model/model-adapter/insight.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/locate-protocol.js +20 -0
- package/dist/lib/ai-model/model-adapter/locate-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/locate.js +87 -0
- package/dist/lib/ai-model/model-adapter/locate.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/planning-protocol.js +20 -0
- package/dist/lib/ai-model/model-adapter/planning-protocol.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/planning.js +86 -0
- package/dist/lib/ai-model/model-adapter/planning.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/resolve.js +88 -0
- package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/types.js +20 -0
- package/dist/lib/ai-model/model-adapter/types.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/actions.js +239 -0
- package/dist/lib/ai-model/models/auto-glm/actions.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/adapter.js +79 -0
- package/dist/lib/ai-model/models/auto-glm/adapter.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/locate.js +45 -0
- package/dist/lib/ai-model/models/auto-glm/locate.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/parser.js +260 -0
- package/dist/lib/ai-model/models/auto-glm/parser.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/planning.js +67 -0
- package/dist/lib/ai-model/models/auto-glm/planning.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/prompt.js +257 -0
- package/dist/lib/ai-model/models/auto-glm/prompt.js.map +1 -0
- package/dist/lib/ai-model/models/deepseek/adapter.js +113 -0
- package/dist/lib/ai-model/models/deepseek/adapter.js.map +1 -0
- package/dist/lib/ai-model/models/deepseek/locate-protocol.js +132 -0
- package/dist/lib/ai-model/models/deepseek/locate-protocol.js.map +1 -0
- package/dist/lib/ai-model/models/default.js +47 -0
- package/dist/lib/ai-model/models/default.js.map +1 -0
- package/dist/lib/ai-model/models/doubao.js +132 -0
- package/dist/lib/ai-model/models/doubao.js.map +1 -0
- package/dist/lib/ai-model/models/gemini.js +137 -0
- package/dist/lib/ai-model/models/gemini.js.map +1 -0
- package/dist/lib/ai-model/models/glm.js +80 -0
- package/dist/lib/ai-model/models/glm.js.map +1 -0
- package/dist/lib/ai-model/models/gpt.js +77 -0
- package/dist/lib/ai-model/models/gpt.js.map +1 -0
- package/dist/lib/ai-model/models/index.js +41 -0
- package/dist/lib/ai-model/models/index.js.map +1 -0
- package/dist/lib/ai-model/models/kimi.js +136 -0
- package/dist/lib/ai-model/models/kimi.js.map +1 -0
- package/dist/lib/ai-model/models/mimo.js +70 -0
- package/dist/lib/ai-model/models/mimo.js.map +1 -0
- package/dist/lib/ai-model/models/qwen.js +173 -0
- package/dist/lib/ai-model/models/qwen.js.map +1 -0
- package/dist/lib/ai-model/models/registry.js +91 -0
- package/dist/lib/ai-model/models/registry.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/actions.js +181 -0
- package/dist/lib/ai-model/models/ui-tars/actions.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/adapter.js +136 -0
- package/dist/lib/ai-model/models/ui-tars/adapter.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/parser.js +74 -0
- package/dist/lib/ai-model/models/ui-tars/parser.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/planning.js +59 -0
- package/dist/lib/ai-model/models/ui-tars/planning.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/prompt.js +73 -0
- package/dist/lib/ai-model/models/ui-tars/prompt.js.map +1 -0
- package/dist/lib/ai-model/models/utils/intent.js +40 -0
- package/dist/lib/ai-model/models/utils/intent.js.map +1 -0
- package/dist/lib/ai-model/prompt/insight/index.js +45 -0
- package/dist/lib/ai-model/prompt/insight/index.js.map +1 -0
- package/dist/lib/ai-model/prompt/insight/system-prompt.js +138 -0
- package/dist/lib/ai-model/prompt/insight/system-prompt.js.map +1 -0
- package/dist/lib/ai-model/prompt/insight/user-prompt.js +60 -0
- package/dist/lib/ai-model/prompt/insight/user-prompt.js.map +1 -0
- package/dist/lib/ai-model/prompt/locate/element-system-prompt.js +46 -0
- package/dist/lib/ai-model/prompt/locate/element-system-prompt.js.map +1 -0
- package/dist/lib/ai-model/prompt/locate/grounding-rules.js +47 -0
- package/dist/lib/ai-model/prompt/locate/grounding-rules.js.map +1 -0
- package/dist/lib/ai-model/prompt/locate/index.js +46 -0
- package/dist/lib/ai-model/prompt/locate/index.js.map +1 -0
- package/dist/lib/ai-model/prompt/locate/search-area-system-prompt.js +43 -0
- package/dist/lib/ai-model/prompt/locate/search-area-system-prompt.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/action-output-example.js +92 -0
- package/dist/lib/ai-model/prompt/planning/action-output-example.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/action-space-description.js +75 -0
- package/dist/lib/ai-model/prompt/planning/action-space-description.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/index.js +63 -0
- package/dist/lib/ai-model/prompt/planning/index.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/multi-turn-example.js +255 -0
- package/dist/lib/ai-model/prompt/planning/multi-turn-example.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/planning-response-example.js +59 -0
- package/dist/lib/ai-model/prompt/planning/planning-response-example.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/sub-goals-text.js +51 -0
- package/dist/lib/ai-model/prompt/planning/sub-goals-text.js.map +1 -0
- package/dist/lib/ai-model/prompt/planning/system-prompt.js +327 -0
- package/dist/lib/ai-model/prompt/planning/system-prompt.js.map +1 -0
- package/dist/lib/ai-model/service-caller/codex-app-server.js +1 -0
- package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +35 -16
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/service-caller/model-call-recorder.js +124 -0
- package/dist/lib/ai-model/service-caller/model-call-recorder.js.map +1 -0
- package/dist/lib/ai-model/service-caller/openai-error.js +184 -0
- package/dist/lib/ai-model/service-caller/openai-error.js.map +1 -0
- package/dist/lib/ai-model/service-caller/proxy-deps.node.js +46 -0
- package/dist/lib/ai-model/service-caller/proxy-deps.node.js.map +1 -0
- package/dist/lib/ai-model/service-caller/proxy-deps.stub.js +49 -0
- package/dist/lib/ai-model/service-caller/proxy-deps.stub.js.map +1 -0
- package/dist/lib/ai-model/service-caller/semantic-retry.js +70 -0
- package/dist/lib/ai-model/service-caller/semantic-retry.js.map +1 -0
- package/dist/lib/ai-model/service-caller/types.js +20 -0
- package/dist/lib/ai-model/service-caller/types.js.map +1 -0
- package/dist/lib/ai-model/shared/action-schema.js +49 -0
- package/dist/lib/ai-model/shared/action-schema.js.map +1 -0
- package/dist/lib/ai-model/shared/json.js +103 -0
- package/dist/lib/ai-model/shared/json.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/bbox.js +106 -0
- package/dist/lib/ai-model/shared/model-locate-result/bbox.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js +44 -0
- package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/errors.js +46 -0
- package/dist/lib/ai-model/shared/model-locate-result/errors.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/factory.js +76 -0
- package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/index.js +66 -0
- package/dist/lib/ai-model/shared/model-locate-result/index.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/parse.js +88 -0
- package/dist/lib/ai-model/shared/model-locate-result/parse.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js +101 -0
- package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js +156 -0
- package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/types.js +46 -0
- package/dist/lib/ai-model/shared/model-locate-result/types.js.map +1 -0
- package/dist/lib/ai-model/shared/multimodal-prompt.js +95 -0
- package/dist/lib/ai-model/shared/multimodal-prompt.js.map +1 -0
- package/dist/lib/ai-model/shared/xml.js +79 -0
- package/dist/lib/ai-model/shared/xml.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/index.js +46 -0
- package/dist/lib/ai-model/workflows/grounding/index.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/locate-result-rect.js +60 -0
- package/dist/lib/ai-model/workflows/grounding/locate-result-rect.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/locate.js +208 -0
- package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js +131 -0
- package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js +52 -0
- package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/search-area.js +92 -0
- package/dist/lib/ai-model/workflows/grounding/search-area.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/section-locate.js +180 -0
- package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/types.js +20 -0
- package/dist/lib/ai-model/workflows/grounding/types.js.map +1 -0
- package/dist/lib/ai-model/workflows/grounding/utils.js +87 -0
- package/dist/lib/ai-model/workflows/grounding/utils.js.map +1 -0
- package/dist/lib/ai-model/workflows/insight/extraction.js +135 -0
- package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -0
- package/dist/lib/ai-model/workflows/insight/index.js +42 -0
- package/dist/lib/ai-model/workflows/insight/index.js.map +1 -0
- package/dist/lib/ai-model/workflows/insight/insight-response-parser.js +60 -0
- package/dist/lib/ai-model/workflows/insight/insight-response-parser.js.map +1 -0
- package/dist/lib/ai-model/workflows/insight/order-sensitive.js +63 -0
- package/dist/lib/ai-model/workflows/insight/order-sensitive.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/conversation-history.js +219 -0
- package/dist/lib/ai-model/workflows/planning/conversation-history.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/custom-planning.js +166 -0
- package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/index.js +49 -0
- package/dist/lib/ai-model/workflows/planning/index.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/locate-normalization.js +75 -0
- package/dist/lib/ai-model/workflows/planning/locate-normalization.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/planning-action-log.js +56 -0
- package/dist/lib/ai-model/workflows/planning/planning-action-log.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/standard-planning-parser.js +142 -0
- package/dist/lib/ai-model/workflows/planning/standard-planning-parser.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/standard-planning.js +253 -0
- package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/types.js +20 -0
- package/dist/lib/ai-model/workflows/planning/types.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/common.js +232 -0
- package/dist/lib/ai-model/workflows/recorder-generation/common.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/index.js +68 -0
- package/dist/lib/ai-model/workflows/recorder-generation/index.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/markdown.js +293 -0
- package/dist/lib/ai-model/workflows/recorder-generation/markdown.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/metadata.js +117 -0
- package/dist/lib/ai-model/workflows/recorder-generation/metadata.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/playwright.js +184 -0
- package/dist/lib/ai-model/workflows/recorder-generation/playwright.js.map +1 -0
- package/dist/lib/ai-model/workflows/recorder-generation/yaml.js +232 -0
- package/dist/lib/ai-model/workflows/recorder-generation/yaml.js.map +1 -0
- package/dist/lib/common.js +18 -1
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/constants.js +38 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/device/index.js.map +1 -1
- package/dist/lib/device/input-strategy.js +80 -0
- package/dist/lib/device/input-strategy.js.map +1 -0
- package/dist/lib/dump/html-utils.js +18 -0
- package/dist/lib/dump/html-utils.js.map +1 -1
- package/dist/lib/dump/image-reference.js +115 -0
- package/dist/lib/dump/image-reference.js.map +1 -0
- package/dist/lib/dump/report-action-dump.js +284 -0
- package/dist/lib/dump/report-action-dump.js.map +1 -0
- package/dist/lib/dump/report-dump-compactor.js +234 -0
- package/dist/lib/dump/report-dump-compactor.js.map +1 -0
- package/dist/lib/dump/screenshot-store.js +146 -38
- package/dist/lib/dump/screenshot-store.js.map +1 -1
- package/dist/lib/dump/task-service-dump.js +54 -0
- package/dist/lib/dump/task-service-dump.js.map +1 -0
- package/dist/lib/dump/task-status.js +55 -0
- package/dist/lib/dump/task-status.js.map +1 -0
- package/dist/lib/element-describer.js +238 -0
- package/dist/lib/element-describer.js.map +1 -0
- package/dist/lib/errors.js +54 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/report-html-template.js +38 -0
- package/dist/lib/report-html-template.js.map +1 -0
- package/dist/lib/report-stats.js +147 -0
- package/dist/lib/report-stats.js.map +1 -0
- package/dist/lib/screenshot-item.js +7 -2
- package/dist/lib/screenshot-item.js.map +1 -1
- package/dist/lib/service/index.js +10 -5
- package/dist/lib/service/index.js.map +1 -1
- package/dist/lib/task-runner.js.map +1 -1
- package/dist/lib/types.js +2 -2
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/yaml/cleanup.js +47 -0
- package/dist/lib/yaml/cleanup.js.map +1 -0
- package/dist/types/agent/agent.d.ts +5 -9
- package/dist/types/agent/cache-config.d.ts +2 -0
- package/dist/types/agent/file-chooser.d.ts +19 -0
- package/dist/types/agent/insight.d.ts +21 -0
- package/dist/types/agent/metrics.d.ts +48 -0
- package/dist/types/agent/progress/ai-act-progress.d.ts +21 -0
- package/dist/types/agent/progress/index.d.ts +2 -0
- package/dist/types/agent/progress/progress-bus.d.ts +33 -0
- package/dist/types/agent/prompt-context.d.ts +3 -0
- package/dist/types/agent/record-to-report.d.ts +2 -0
- package/dist/types/agent/run-gherkin-scenario.d.ts +26 -0
- package/dist/types/agent/run-markdown.d.ts +6 -0
- package/dist/types/agent/screenshot-preparation.d.ts +20 -0
- package/dist/types/agent/ui-observer.d.ts +103 -0
- package/dist/types/agent/utils.d.ts +12 -1
- package/dist/types/ai-model/connectivity/fixture.d.ts +5 -0
- package/dist/types/ai-model/connectivity/index.d.ts +1 -0
- package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts +11 -0
- package/dist/types/ai-model/index.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/chat-completion.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/custom-planning-action.d.ts +25 -0
- package/dist/types/ai-model/model-adapter/custom-planning-types.d.ts +31 -0
- package/dist/types/ai-model/model-adapter/default-insight-protocol.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/default-locate-protocol.d.ts +7 -0
- package/dist/types/ai-model/model-adapter/default-planning-protocol.d.ts +25 -0
- package/dist/types/ai-model/model-adapter/image-preprocess.d.ts +30 -0
- package/dist/types/ai-model/model-adapter/index.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/insight-protocol.d.ts +24 -0
- package/dist/types/ai-model/model-adapter/insight.d.ts +3 -0
- package/dist/types/ai-model/model-adapter/locate-protocol.d.ts +23 -0
- package/dist/types/ai-model/model-adapter/locate.d.ts +4 -0
- package/dist/types/ai-model/model-adapter/planning-protocol.d.ts +53 -0
- package/dist/types/ai-model/model-adapter/planning.d.ts +6 -0
- package/dist/types/ai-model/model-adapter/resolve.d.ts +12 -0
- package/dist/types/ai-model/model-adapter/types.d.ts +218 -0
- package/dist/types/ai-model/models/auto-glm/actions.d.ts +81 -0
- package/dist/types/ai-model/models/auto-glm/adapter.d.ts +5 -0
- package/dist/types/ai-model/models/auto-glm/locate.d.ts +2 -0
- package/dist/types/ai-model/models/auto-glm/parser.d.ts +14 -0
- package/dist/types/ai-model/models/auto-glm/planning.d.ts +5 -0
- package/dist/types/ai-model/models/auto-glm/prompt.d.ts +4 -0
- package/dist/types/ai-model/models/deepseek/adapter.d.ts +39 -0
- package/dist/types/ai-model/models/deepseek/locate-protocol.d.ts +5 -0
- package/dist/types/ai-model/models/default.d.ts +2 -0
- package/dist/types/ai-model/models/doubao.d.ts +7 -0
- package/dist/types/ai-model/models/gemini.d.ts +37 -0
- package/dist/types/ai-model/models/glm.d.ts +21 -0
- package/dist/types/ai-model/models/gpt.d.ts +20 -0
- package/dist/types/ai-model/models/index.d.ts +2 -0
- package/dist/types/ai-model/models/kimi.d.ts +45 -0
- package/dist/types/ai-model/models/mimo.d.ts +10 -0
- package/dist/types/ai-model/models/qwen.d.ts +33 -0
- package/dist/types/ai-model/models/registry.d.ts +187 -0
- package/dist/types/ai-model/models/ui-tars/actions.d.ts +3 -0
- package/dist/types/ai-model/models/ui-tars/adapter.d.ts +6 -0
- package/dist/types/ai-model/models/ui-tars/parser.d.ts +72 -0
- package/dist/types/ai-model/models/ui-tars/planning.d.ts +4 -0
- package/dist/types/ai-model/models/ui-tars/prompt.d.ts +2 -0
- package/dist/types/ai-model/models/utils/intent.d.ts +2 -0
- package/dist/types/ai-model/prompt/insight/index.d.ts +2 -0
- package/dist/types/ai-model/prompt/insight/system-prompt.d.ts +6 -0
- package/dist/types/ai-model/prompt/insight/user-prompt.d.ts +3 -0
- package/dist/types/ai-model/prompt/locate/element-system-prompt.d.ts +4 -0
- package/dist/types/ai-model/prompt/locate/grounding-rules.d.ts +1 -0
- package/dist/types/ai-model/prompt/locate/index.d.ts +3 -0
- package/dist/types/ai-model/prompt/locate/search-area-system-prompt.d.ts +4 -0
- package/dist/types/ai-model/prompt/planning/action-output-example.d.ts +17 -0
- package/dist/types/ai-model/prompt/planning/action-space-description.d.ts +11 -0
- package/dist/types/ai-model/prompt/planning/index.d.ts +6 -0
- package/dist/types/ai-model/prompt/planning/multi-turn-example.d.ts +10 -0
- package/dist/types/ai-model/prompt/planning/planning-response-example.d.ts +28 -0
- package/dist/types/ai-model/prompt/planning/sub-goals-text.d.ts +2 -0
- package/dist/types/ai-model/prompt/planning/system-prompt.d.ts +18 -0
- package/dist/types/ai-model/service-caller/index.d.ts +21 -6
- package/dist/types/ai-model/service-caller/model-call-recorder.d.ts +12 -0
- package/dist/types/ai-model/service-caller/openai-error.d.ts +26 -0
- package/dist/types/ai-model/service-caller/proxy-deps.node.d.ts +2 -0
- package/dist/types/ai-model/service-caller/proxy-deps.stub.d.ts +2 -0
- package/dist/types/ai-model/service-caller/semantic-retry.d.ts +30 -0
- package/dist/types/ai-model/service-caller/types.d.ts +2 -0
- package/dist/types/ai-model/shared/action-schema.d.ts +4 -0
- package/dist/types/ai-model/shared/json.d.ts +26 -0
- package/dist/types/ai-model/shared/model-locate-result/bbox.d.ts +6 -0
- package/dist/types/ai-model/shared/model-locate-result/coordinate-distance.d.ts +4 -0
- package/dist/types/ai-model/shared/model-locate-result/errors.d.ts +2 -0
- package/dist/types/ai-model/shared/model-locate-result/factory.d.ts +3 -0
- package/dist/types/ai-model/shared/model-locate-result/index.d.ts +7 -0
- package/dist/types/ai-model/shared/model-locate-result/parse.d.ts +8 -0
- package/dist/types/ai-model/shared/model-locate-result/pixel-bbox-mapper.d.ts +7 -0
- package/dist/types/ai-model/shared/model-locate-result/prompt-spec.d.ts +6 -0
- package/dist/types/ai-model/shared/model-locate-result/types.d.ts +150 -0
- package/dist/types/ai-model/shared/multimodal-prompt.d.ts +13 -0
- package/dist/types/ai-model/shared/xml.d.ts +15 -0
- package/dist/types/ai-model/workflows/grounding/index.d.ts +3 -0
- package/dist/types/ai-model/workflows/grounding/locate-result-rect.d.ts +5 -0
- package/dist/types/ai-model/workflows/grounding/locate.d.ts +7 -0
- package/dist/types/ai-model/workflows/grounding/planning-action-locate.d.ts +4 -0
- package/dist/types/ai-model/workflows/grounding/search-area-mapping.d.ts +4 -0
- package/dist/types/ai-model/workflows/grounding/search-area.d.ts +18 -0
- package/dist/types/ai-model/workflows/grounding/section-locate.d.ts +16 -0
- package/dist/types/ai-model/workflows/grounding/types.d.ts +56 -0
- package/dist/types/ai-model/workflows/grounding/utils.d.ts +25 -0
- package/dist/types/ai-model/workflows/insight/extraction.d.ts +18 -0
- package/dist/types/ai-model/workflows/insight/index.d.ts +2 -0
- package/dist/types/ai-model/workflows/insight/insight-response-parser.d.ts +4 -0
- package/dist/types/ai-model/workflows/insight/order-sensitive.d.ts +6 -0
- package/dist/types/ai-model/workflows/planning/conversation-history.d.ts +105 -0
- package/dist/types/ai-model/workflows/planning/custom-planning.d.ts +7 -0
- package/dist/types/ai-model/workflows/planning/index.d.ts +3 -0
- package/dist/types/ai-model/workflows/planning/locate-normalization.d.ts +12 -0
- package/dist/types/ai-model/workflows/planning/planning-action-log.d.ts +2 -0
- package/dist/types/ai-model/workflows/planning/standard-planning-parser.d.ts +31 -0
- package/dist/types/ai-model/workflows/planning/standard-planning.d.ts +4 -0
- package/dist/types/ai-model/workflows/planning/types.d.ts +16 -0
- package/dist/types/ai-model/workflows/recorder-generation/common.d.ts +89 -0
- package/dist/types/ai-model/workflows/recorder-generation/index.d.ts +7 -0
- package/dist/types/ai-model/workflows/recorder-generation/markdown.d.ts +7 -0
- package/dist/types/ai-model/workflows/recorder-generation/metadata.d.ts +13 -0
- package/dist/types/ai-model/workflows/recorder-generation/playwright.d.ts +26 -0
- package/dist/types/ai-model/workflows/recorder-generation/yaml.d.ts +17 -0
- package/dist/types/common.d.ts +2 -0
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/device/index.d.ts +15 -4
- package/dist/types/device/input-strategy.d.ts +44 -0
- package/dist/types/dump/html-utils.d.ts +1 -0
- package/dist/types/dump/image-reference.d.ts +36 -0
- package/dist/types/dump/report-action-dump.d.ts +127 -0
- package/dist/types/dump/report-dump-compactor.d.ts +7 -0
- package/dist/types/dump/screenshot-store.d.ts +32 -15
- package/dist/types/dump/task-service-dump.d.ts +3 -0
- package/dist/types/dump/task-status.d.ts +41 -0
- package/dist/types/element-describer.d.ts +43 -0
- package/dist/types/errors.d.ts +5 -0
- package/dist/types/report-html-template.d.ts +1 -0
- package/dist/types/report-stats.d.ts +39 -0
- package/dist/types/screenshot-item.d.ts +1 -0
- package/dist/types/service/index.d.ts +6 -2
- package/dist/types/task-runner.d.ts +6 -0
- package/dist/types/types.d.ts +98 -5
- package/dist/types/yaml/cleanup.d.ts +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const stepKeywordPattern = /^(Given|When|Then|And|But)\s+(.+)$/i;
|
|
2
|
+
const headerPattern = /^(Scenario):\s*(.*)$/i;
|
|
3
|
+
const unsupportedHeaderPattern = /^(Feature|Background|Scenario Outline|Scenario Template|Examples|Rule):/i;
|
|
4
|
+
const normalizeStepKeyword = (keyword)=>{
|
|
5
|
+
const lowerKeyword = keyword.toLowerCase();
|
|
6
|
+
if ('given' === lowerKeyword) return 'Given';
|
|
7
|
+
if ('when' === lowerKeyword) return 'When';
|
|
8
|
+
if ('then' === lowerKeyword) return 'Then';
|
|
9
|
+
if ('and' === lowerKeyword) return 'And';
|
|
10
|
+
return 'But';
|
|
11
|
+
};
|
|
12
|
+
const isPrimaryKeyword = (keyword)=>'Given' === keyword || 'When' === keyword || 'Then' === keyword;
|
|
13
|
+
const resolveSteps = (steps)=>{
|
|
14
|
+
let previousPrimaryKeyword;
|
|
15
|
+
return steps.map((step)=>{
|
|
16
|
+
const effectiveKeyword = isPrimaryKeyword(step.keyword) ? step.keyword : previousPrimaryKeyword;
|
|
17
|
+
if (!effectiveKeyword) throw new Error(`runGherkinScenario cannot resolve "${step.keyword}" at line ${step.lineNumber}; use Given, When, or Then before ${step.keyword}.`);
|
|
18
|
+
previousPrimaryKeyword = effectiveKeyword;
|
|
19
|
+
return {
|
|
20
|
+
...step,
|
|
21
|
+
effectiveKeyword
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const throwIfAborted = (abortSignal)=>{
|
|
26
|
+
if (!abortSignal?.aborted) return;
|
|
27
|
+
if ('function' == typeof abortSignal.throwIfAborted) abortSignal.throwIfAborted();
|
|
28
|
+
throw new Error(`runGherkinScenario aborted: ${abortSignal.reason || 'signal already aborted'}`);
|
|
29
|
+
};
|
|
30
|
+
const parseGherkinScenario = (scenarioText)=>{
|
|
31
|
+
const lines = scenarioText.split(/\r?\n/);
|
|
32
|
+
const scenarioSteps = [];
|
|
33
|
+
const anonymousSteps = [];
|
|
34
|
+
let scenario;
|
|
35
|
+
let scenarioCount = 0;
|
|
36
|
+
let section = 'prelude';
|
|
37
|
+
for (const [lineIndex, rawLine] of lines.entries()){
|
|
38
|
+
const lineNumber = lineIndex + 1;
|
|
39
|
+
const line = rawLine.trim();
|
|
40
|
+
if (!line || line.startsWith('#') || line.startsWith('@')) continue;
|
|
41
|
+
if ('"""' === line || "'''" === line) throw new Error(`runGherkinScenario does not support doc strings; found one at line ${lineNumber}.`);
|
|
42
|
+
if (line.startsWith('|')) throw new Error(`runGherkinScenario does not support data tables; found one at line ${lineNumber}.`);
|
|
43
|
+
if (unsupportedHeaderPattern.test(line)) throw new Error(`runGherkinScenario does not support "${line}" at line ${lineNumber}.`);
|
|
44
|
+
const headerMatch = line.match(headerPattern);
|
|
45
|
+
if (headerMatch) {
|
|
46
|
+
scenarioCount += 1;
|
|
47
|
+
scenario = headerMatch[2].trim() || void 0;
|
|
48
|
+
section = 'scenario';
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const stepMatch = line.match(stepKeywordPattern);
|
|
52
|
+
if (stepMatch) {
|
|
53
|
+
const step = {
|
|
54
|
+
keyword: normalizeStepKeyword(stepMatch[1]),
|
|
55
|
+
text: stepMatch[2].trim(),
|
|
56
|
+
lineNumber
|
|
57
|
+
};
|
|
58
|
+
if ('scenario' === section) scenarioSteps.push(step);
|
|
59
|
+
else anonymousSteps.push(step);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`runGherkinScenario does not support content at line ${lineNumber}: ${line}`);
|
|
63
|
+
}
|
|
64
|
+
if (scenarioCount > 1) throw new Error(`runGherkinScenario expects exactly one Scenario, but found ${scenarioCount}.`);
|
|
65
|
+
if (1 === scenarioCount && anonymousSteps.length > 0) throw new Error('runGherkinScenario cannot mix anonymous steps with a Scenario block.');
|
|
66
|
+
const rawSteps = 1 === scenarioCount ? scenarioSteps : anonymousSteps;
|
|
67
|
+
if (0 === rawSteps.length) throw new Error('runGherkinScenario requires at least one Gherkin step.');
|
|
68
|
+
return {
|
|
69
|
+
scenario,
|
|
70
|
+
steps: resolveSteps(rawSteps)
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
const buildStepPrompt = (step)=>{
|
|
74
|
+
if ('Given' === step.effectiveKeyword) return `Set up this precondition: ${step.text}`;
|
|
75
|
+
if ('When' === step.effectiveKeyword) return `Perform this user action: ${step.text}`;
|
|
76
|
+
return `Verify that ${step.text}`;
|
|
77
|
+
};
|
|
78
|
+
const describeStepExecution = (step, action)=>{
|
|
79
|
+
const keywordMapping = step.keyword === step.effectiveKeyword ? step.keyword : `${step.keyword} as ${step.effectiveKeyword}`;
|
|
80
|
+
if ('Given' === step.effectiveKeyword) return `setting up the precondition (${keywordMapping} -> ${action})`;
|
|
81
|
+
if ('When' === step.effectiveKeyword) return `performing the user action (${keywordMapping} -> ${action})`;
|
|
82
|
+
return `verifying the expected result (${keywordMapping} -> ${action})`;
|
|
83
|
+
};
|
|
84
|
+
const describeErrorCause = (error)=>{
|
|
85
|
+
if (error instanceof Error && error.message) return ` Original error: ${error.message}`;
|
|
86
|
+
return '';
|
|
87
|
+
};
|
|
88
|
+
const runGherkinScenario = async (agent, scenarioText, opt)=>{
|
|
89
|
+
const parsedScenario = parseGherkinScenario(scenarioText);
|
|
90
|
+
const aiActOptions = {
|
|
91
|
+
...opt,
|
|
92
|
+
cacheable: false
|
|
93
|
+
};
|
|
94
|
+
for (const step of parsedScenario.steps){
|
|
95
|
+
throwIfAborted(opt?.abortSignal);
|
|
96
|
+
const action = 'Then' === step.effectiveKeyword ? 'aiAssert' : 'aiAct';
|
|
97
|
+
const prompt = buildStepPrompt(step);
|
|
98
|
+
try {
|
|
99
|
+
if ('aiAct' === action) await agent.aiAct(prompt, aiActOptions);
|
|
100
|
+
else if (opt?.context || opt?.abortSignal) await agent.aiAssert(prompt, void 0, {
|
|
101
|
+
context: opt.context,
|
|
102
|
+
abortSignal: opt.abortSignal
|
|
103
|
+
});
|
|
104
|
+
else await agent.aiAssert(prompt);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(`runGherkinScenario failed while ${describeStepExecution(step, action)} at line ${step.lineNumber}: ${step.keyword} ${step.text}.${describeErrorCause(error)}`, {
|
|
107
|
+
cause: error
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
export { parseGherkinScenario, runGherkinScenario };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=run-gherkin-scenario.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent/run-gherkin-scenario.mjs","sources":["../../../src/agent/run-gherkin-scenario.ts"],"sourcesContent":["import type { AiActOptions } from './agent';\n\nexport type GherkinStepKeyword = 'Given' | 'When' | 'Then' | 'And' | 'But';\n\ntype RunGherkinScenarioStepAction = 'aiAct' | 'aiAssert';\n\nexport type RunGherkinScenarioOptions = AiActOptions & {\n context?: string;\n};\n\ntype GherkinPrimaryKeyword = 'Given' | 'When' | 'Then';\n\ntype ParsedGherkinStep = {\n keyword: GherkinStepKeyword;\n effectiveKeyword: GherkinPrimaryKeyword;\n text: string;\n lineNumber: number;\n};\n\ntype RawGherkinStep = {\n keyword: GherkinStepKeyword;\n text: string;\n lineNumber: number;\n};\n\ntype ParsedGherkinScenario = {\n scenario?: string;\n steps: ParsedGherkinStep[];\n};\n\ntype GherkinScenarioAgent = {\n aiAct: (taskPrompt: string, opt?: AiActOptions) => Promise<unknown>;\n aiAssert: (\n assertion: string,\n msg?: string,\n opt?: { context?: string; abortSignal?: AbortSignal },\n ) => Promise<unknown>;\n};\n\nconst stepKeywordPattern = /^(Given|When|Then|And|But)\\s+(.+)$/i;\nconst headerPattern = /^(Scenario):\\s*(.*)$/i;\nconst unsupportedHeaderPattern =\n /^(Feature|Background|Scenario Outline|Scenario Template|Examples|Rule):/i;\n\nconst normalizeStepKeyword = (keyword: string): GherkinStepKeyword => {\n const lowerKeyword = keyword.toLowerCase();\n if (lowerKeyword === 'given') return 'Given';\n if (lowerKeyword === 'when') return 'When';\n if (lowerKeyword === 'then') return 'Then';\n if (lowerKeyword === 'and') return 'And';\n return 'But';\n};\n\nconst isPrimaryKeyword = (\n keyword: GherkinStepKeyword,\n): keyword is GherkinPrimaryKeyword => {\n return keyword === 'Given' || keyword === 'When' || keyword === 'Then';\n};\n\nconst resolveSteps = (steps: RawGherkinStep[]): ParsedGherkinStep[] => {\n let previousPrimaryKeyword: GherkinPrimaryKeyword | undefined;\n\n return steps.map((step) => {\n const effectiveKeyword = isPrimaryKeyword(step.keyword)\n ? step.keyword\n : previousPrimaryKeyword;\n\n if (!effectiveKeyword) {\n throw new Error(\n `runGherkinScenario cannot resolve \"${step.keyword}\" at line ${step.lineNumber}; use Given, When, or Then before ${step.keyword}.`,\n );\n }\n\n previousPrimaryKeyword = effectiveKeyword;\n\n return {\n ...step,\n effectiveKeyword,\n };\n });\n};\n\nconst throwIfAborted = (abortSignal: AbortSignal | undefined) => {\n if (!abortSignal?.aborted) {\n return;\n }\n\n if (typeof abortSignal.throwIfAborted === 'function') {\n abortSignal.throwIfAborted();\n }\n\n throw new Error(\n `runGherkinScenario aborted: ${abortSignal.reason || 'signal already aborted'}`,\n );\n};\n\nexport const parseGherkinScenario = (\n scenarioText: string,\n): ParsedGherkinScenario => {\n const lines = scenarioText.split(/\\r?\\n/);\n const scenarioSteps: RawGherkinStep[] = [];\n const anonymousSteps: RawGherkinStep[] = [];\n let scenario: string | undefined;\n let scenarioCount = 0;\n let section: 'prelude' | 'scenario' = 'prelude';\n\n for (const [lineIndex, rawLine] of lines.entries()) {\n const lineNumber = lineIndex + 1;\n const line = rawLine.trim();\n\n if (!line || line.startsWith('#') || line.startsWith('@')) {\n continue;\n }\n\n if (line === '\"\"\"' || line === \"'''\") {\n throw new Error(\n `runGherkinScenario does not support doc strings; found one at line ${lineNumber}.`,\n );\n }\n\n if (line.startsWith('|')) {\n throw new Error(\n `runGherkinScenario does not support data tables; found one at line ${lineNumber}.`,\n );\n }\n\n if (unsupportedHeaderPattern.test(line)) {\n throw new Error(\n `runGherkinScenario does not support \"${line}\" at line ${lineNumber}.`,\n );\n }\n\n const headerMatch = line.match(headerPattern);\n if (headerMatch) {\n scenarioCount += 1;\n scenario = headerMatch[2].trim() || undefined;\n section = 'scenario';\n continue;\n }\n\n const stepMatch = line.match(stepKeywordPattern);\n if (stepMatch) {\n const step = {\n keyword: normalizeStepKeyword(stepMatch[1]),\n text: stepMatch[2].trim(),\n lineNumber,\n };\n\n if (section === 'scenario') {\n scenarioSteps.push(step);\n } else {\n anonymousSteps.push(step);\n }\n\n continue;\n }\n\n throw new Error(\n `runGherkinScenario does not support content at line ${lineNumber}: ${line}`,\n );\n }\n\n if (scenarioCount > 1) {\n throw new Error(\n `runGherkinScenario expects exactly one Scenario, but found ${scenarioCount}.`,\n );\n }\n\n if (scenarioCount === 1 && anonymousSteps.length > 0) {\n throw new Error(\n 'runGherkinScenario cannot mix anonymous steps with a Scenario block.',\n );\n }\n\n const rawSteps = scenarioCount === 1 ? scenarioSteps : anonymousSteps;\n\n if (rawSteps.length === 0) {\n throw new Error('runGherkinScenario requires at least one Gherkin step.');\n }\n\n return {\n scenario,\n steps: resolveSteps(rawSteps),\n };\n};\n\nconst buildStepPrompt = (step: ParsedGherkinStep) => {\n if (step.effectiveKeyword === 'Given') {\n return `Set up this precondition: ${step.text}`;\n }\n\n if (step.effectiveKeyword === 'When') {\n return `Perform this user action: ${step.text}`;\n }\n\n return `Verify that ${step.text}`;\n};\n\nconst describeStepExecution = (\n step: ParsedGherkinStep,\n action: RunGherkinScenarioStepAction,\n) => {\n const keywordMapping =\n step.keyword === step.effectiveKeyword\n ? step.keyword\n : `${step.keyword} as ${step.effectiveKeyword}`;\n\n if (step.effectiveKeyword === 'Given') {\n return `setting up the precondition (${keywordMapping} -> ${action})`;\n }\n\n if (step.effectiveKeyword === 'When') {\n return `performing the user action (${keywordMapping} -> ${action})`;\n }\n\n return `verifying the expected result (${keywordMapping} -> ${action})`;\n};\n\nconst describeErrorCause = (error: unknown) => {\n if (error instanceof Error && error.message) {\n return ` Original error: ${error.message}`;\n }\n\n return '';\n};\n\nexport const runGherkinScenario = async (\n agent: GherkinScenarioAgent,\n scenarioText: string,\n opt?: RunGherkinScenarioOptions,\n): Promise<void> => {\n const parsedScenario = parseGherkinScenario(scenarioText);\n const aiActOptions: AiActOptions = {\n ...opt,\n cacheable: false,\n };\n\n for (const step of parsedScenario.steps) {\n throwIfAborted(opt?.abortSignal);\n\n const action: RunGherkinScenarioStepAction =\n step.effectiveKeyword === 'Then' ? 'aiAssert' : 'aiAct';\n const prompt = buildStepPrompt(step);\n\n try {\n if (action === 'aiAct') {\n await agent.aiAct(prompt, aiActOptions);\n } else if (opt?.context || opt?.abortSignal) {\n await agent.aiAssert(prompt, undefined, {\n context: opt.context,\n abortSignal: opt.abortSignal,\n });\n } else {\n await agent.aiAssert(prompt);\n }\n } catch (error) {\n throw new Error(\n `runGherkinScenario failed while ${describeStepExecution(\n step,\n action,\n )} at line ${step.lineNumber}: ${step.keyword} ${step.text}.${describeErrorCause(\n error,\n )}`,\n {\n cause: error,\n },\n );\n }\n }\n};\n"],"names":["stepKeywordPattern","headerPattern","unsupportedHeaderPattern","normalizeStepKeyword","keyword","lowerKeyword","isPrimaryKeyword","resolveSteps","steps","previousPrimaryKeyword","step","effectiveKeyword","Error","throwIfAborted","abortSignal","parseGherkinScenario","scenarioText","lines","scenarioSteps","anonymousSteps","scenario","scenarioCount","section","lineIndex","rawLine","lineNumber","line","headerMatch","undefined","stepMatch","rawSteps","buildStepPrompt","describeStepExecution","action","keywordMapping","describeErrorCause","error","runGherkinScenario","agent","opt","parsedScenario","aiActOptions","prompt"],"mappings":"AAuCA,MAAMA,qBAAqB;AAC3B,MAAMC,gBAAgB;AACtB,MAAMC,2BACJ;AAEF,MAAMC,uBAAuB,CAACC;IAC5B,MAAMC,eAAeD,QAAQ,WAAW;IACxC,IAAIC,AAAiB,YAAjBA,cAA0B,OAAO;IACrC,IAAIA,AAAiB,WAAjBA,cAAyB,OAAO;IACpC,IAAIA,AAAiB,WAAjBA,cAAyB,OAAO;IACpC,IAAIA,AAAiB,UAAjBA,cAAwB,OAAO;IACnC,OAAO;AACT;AAEA,MAAMC,mBAAmB,CACvBF,UAEOA,AAAY,YAAZA,WAAuBA,AAAY,WAAZA,WAAsBA,AAAY,WAAZA;AAGtD,MAAMG,eAAe,CAACC;IACpB,IAAIC;IAEJ,OAAOD,MAAM,GAAG,CAAC,CAACE;QAChB,MAAMC,mBAAmBL,iBAAiBI,KAAK,OAAO,IAClDA,KAAK,OAAO,GACZD;QAEJ,IAAI,CAACE,kBACH,MAAM,IAAIC,MACR,CAAC,mCAAmC,EAAEF,KAAK,OAAO,CAAC,UAAU,EAAEA,KAAK,UAAU,CAAC,kCAAkC,EAAEA,KAAK,OAAO,CAAC,CAAC,CAAC;QAItID,yBAAyBE;QAEzB,OAAO;YACL,GAAGD,IAAI;YACPC;QACF;IACF;AACF;AAEA,MAAME,iBAAiB,CAACC;IACtB,IAAI,CAACA,aAAa,SAChB;IAGF,IAAI,AAAsC,cAAtC,OAAOA,YAAY,cAAc,EACnCA,YAAY,cAAc;IAG5B,MAAM,IAAIF,MACR,CAAC,4BAA4B,EAAEE,YAAY,MAAM,IAAI,0BAA0B;AAEnF;AAEO,MAAMC,uBAAuB,CAClCC;IAEA,MAAMC,QAAQD,aAAa,KAAK,CAAC;IACjC,MAAME,gBAAkC,EAAE;IAC1C,MAAMC,iBAAmC,EAAE;IAC3C,IAAIC;IACJ,IAAIC,gBAAgB;IACpB,IAAIC,UAAkC;IAEtC,KAAK,MAAM,CAACC,WAAWC,QAAQ,IAAIP,MAAM,OAAO,GAAI;QAClD,MAAMQ,aAAaF,YAAY;QAC/B,MAAMG,OAAOF,QAAQ,IAAI;QAEzB,IAAI,CAACE,QAAQA,KAAK,UAAU,CAAC,QAAQA,KAAK,UAAU,CAAC,MACnD;QAGF,IAAIA,AAAS,UAATA,QAAkBA,AAAS,UAATA,MACpB,MAAM,IAAId,MACR,CAAC,mEAAmE,EAAEa,WAAW,CAAC,CAAC;QAIvF,IAAIC,KAAK,UAAU,CAAC,MAClB,MAAM,IAAId,MACR,CAAC,mEAAmE,EAAEa,WAAW,CAAC,CAAC;QAIvF,IAAIvB,yBAAyB,IAAI,CAACwB,OAChC,MAAM,IAAId,MACR,CAAC,qCAAqC,EAAEc,KAAK,UAAU,EAAED,WAAW,CAAC,CAAC;QAI1E,MAAME,cAAcD,KAAK,KAAK,CAACzB;QAC/B,IAAI0B,aAAa;YACfN,iBAAiB;YACjBD,WAAWO,WAAW,CAAC,EAAE,CAAC,IAAI,MAAMC;YACpCN,UAAU;YACV;QACF;QAEA,MAAMO,YAAYH,KAAK,KAAK,CAAC1B;QAC7B,IAAI6B,WAAW;YACb,MAAMnB,OAAO;gBACX,SAASP,qBAAqB0B,SAAS,CAAC,EAAE;gBAC1C,MAAMA,SAAS,CAAC,EAAE,CAAC,IAAI;gBACvBJ;YACF;YAEA,IAAIH,AAAY,eAAZA,SACFJ,cAAc,IAAI,CAACR;iBAEnBS,eAAe,IAAI,CAACT;YAGtB;QACF;QAEA,MAAM,IAAIE,MACR,CAAC,oDAAoD,EAAEa,WAAW,EAAE,EAAEC,MAAM;IAEhF;IAEA,IAAIL,gBAAgB,GAClB,MAAM,IAAIT,MACR,CAAC,2DAA2D,EAAES,cAAc,CAAC,CAAC;IAIlF,IAAIA,AAAkB,MAAlBA,iBAAuBF,eAAe,MAAM,GAAG,GACjD,MAAM,IAAIP,MACR;IAIJ,MAAMkB,WAAWT,AAAkB,MAAlBA,gBAAsBH,gBAAgBC;IAEvD,IAAIW,AAAoB,MAApBA,SAAS,MAAM,EACjB,MAAM,IAAIlB,MAAM;IAGlB,OAAO;QACLQ;QACA,OAAOb,aAAauB;IACtB;AACF;AAEA,MAAMC,kBAAkB,CAACrB;IACvB,IAAIA,AAA0B,YAA1BA,KAAK,gBAAgB,EACvB,OAAO,CAAC,0BAA0B,EAAEA,KAAK,IAAI,EAAE;IAGjD,IAAIA,AAA0B,WAA1BA,KAAK,gBAAgB,EACvB,OAAO,CAAC,0BAA0B,EAAEA,KAAK,IAAI,EAAE;IAGjD,OAAO,CAAC,YAAY,EAAEA,KAAK,IAAI,EAAE;AACnC;AAEA,MAAMsB,wBAAwB,CAC5BtB,MACAuB;IAEA,MAAMC,iBACJxB,KAAK,OAAO,KAAKA,KAAK,gBAAgB,GAClCA,KAAK,OAAO,GACZ,GAAGA,KAAK,OAAO,CAAC,IAAI,EAAEA,KAAK,gBAAgB,EAAE;IAEnD,IAAIA,AAA0B,YAA1BA,KAAK,gBAAgB,EACvB,OAAO,CAAC,6BAA6B,EAAEwB,eAAe,IAAI,EAAED,OAAO,CAAC,CAAC;IAGvE,IAAIvB,AAA0B,WAA1BA,KAAK,gBAAgB,EACvB,OAAO,CAAC,4BAA4B,EAAEwB,eAAe,IAAI,EAAED,OAAO,CAAC,CAAC;IAGtE,OAAO,CAAC,+BAA+B,EAAEC,eAAe,IAAI,EAAED,OAAO,CAAC,CAAC;AACzE;AAEA,MAAME,qBAAqB,CAACC;IAC1B,IAAIA,iBAAiBxB,SAASwB,MAAM,OAAO,EACzC,OAAO,CAAC,iBAAiB,EAAEA,MAAM,OAAO,EAAE;IAG5C,OAAO;AACT;AAEO,MAAMC,qBAAqB,OAChCC,OACAtB,cACAuB;IAEA,MAAMC,iBAAiBzB,qBAAqBC;IAC5C,MAAMyB,eAA6B;QACjC,GAAGF,GAAG;QACN,WAAW;IACb;IAEA,KAAK,MAAM7B,QAAQ8B,eAAe,KAAK,CAAE;QACvC3B,eAAe0B,KAAK;QAEpB,MAAMN,SACJvB,AAA0B,WAA1BA,KAAK,gBAAgB,GAAc,aAAa;QAClD,MAAMgC,SAASX,gBAAgBrB;QAE/B,IAAI;YACF,IAAIuB,AAAW,YAAXA,QACF,MAAMK,MAAM,KAAK,CAACI,QAAQD;iBACrB,IAAIF,KAAK,WAAWA,KAAK,aAC9B,MAAMD,MAAM,QAAQ,CAACI,QAAQd,QAAW;gBACtC,SAASW,IAAI,OAAO;gBACpB,aAAaA,IAAI,WAAW;YAC9B;iBAEA,MAAMD,MAAM,QAAQ,CAACI;QAEzB,EAAE,OAAON,OAAO;YACd,MAAM,IAAIxB,MACR,CAAC,gCAAgC,EAAEoB,sBACjCtB,MACAuB,QACA,SAAS,EAAEvB,KAAK,UAAU,CAAC,EAAE,EAAEA,KAAK,OAAO,CAAC,CAAC,EAAEA,KAAK,IAAI,CAAC,CAAC,EAAEyB,mBAC5DC,QACC,EACH;gBACE,OAAOA;YACT;QAEJ;IACF;AACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
2
|
+
const MAX_MARKDOWN_IMAGES = 20;
|
|
3
|
+
const REFERENCE_IMAGE_PREFIX = '参考图片';
|
|
4
|
+
const imageNameForIndex = (index)=>`${REFERENCE_IMAGE_PREFIX}-${String(index + 1).padStart(3, '0')}`;
|
|
5
|
+
const formatSource = (sourcePath)=>sourcePath ? ` in ${sourcePath}` : '';
|
|
6
|
+
const hasUrlScheme = (url)=>/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(url);
|
|
7
|
+
const resolveMarkdownImageUrl = (url, sourcePath)=>{
|
|
8
|
+
if (!sourcePath || hasUrlScheme(url) || isAbsolute(url)) return url;
|
|
9
|
+
return resolve(dirname(sourcePath), url);
|
|
10
|
+
};
|
|
11
|
+
const replaceMarkdownImages = (tree, sourcePath)=>{
|
|
12
|
+
const images = [];
|
|
13
|
+
const visitChildren = (node)=>{
|
|
14
|
+
if (!Array.isArray(node.children)) return;
|
|
15
|
+
node.children = node.children.map((child)=>{
|
|
16
|
+
if ('imageReference' === child.type) {
|
|
17
|
+
const identifier = child.identifier || child.label || 'unknown';
|
|
18
|
+
throw new Error(`runMarkdown does not support reference-style image "${identifier}"${formatSource(sourcePath)}. Use direct image syntax instead.`);
|
|
19
|
+
}
|
|
20
|
+
if ('image' === child.type) {
|
|
21
|
+
const name = imageNameForIndex(images.length);
|
|
22
|
+
if (!child.url) throw new Error(`Markdown image ${name}${formatSource(sourcePath)} is missing a URL.`);
|
|
23
|
+
images.push({
|
|
24
|
+
name,
|
|
25
|
+
url: resolveMarkdownImageUrl(child.url, sourcePath)
|
|
26
|
+
});
|
|
27
|
+
if (images.length > MAX_MARKDOWN_IMAGES) throw new Error(`runMarkdown supports at most ${MAX_MARKDOWN_IMAGES} images, but found ${images.length} images${formatSource(sourcePath)}.`);
|
|
28
|
+
return {
|
|
29
|
+
type: 'text',
|
|
30
|
+
value: name
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
visitChildren(child);
|
|
34
|
+
return child;
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
visitChildren(tree);
|
|
38
|
+
return images;
|
|
39
|
+
};
|
|
40
|
+
const markdownToAiActPrompt = async (markdown, sourcePath)=>{
|
|
41
|
+
const fromMarkdownModuleName = 'mdast-util-from-markdown';
|
|
42
|
+
const toMarkdownModuleName = 'mdast-util-to-markdown';
|
|
43
|
+
const { fromMarkdown } = await import(fromMarkdownModuleName);
|
|
44
|
+
const { toMarkdown } = await import(toMarkdownModuleName);
|
|
45
|
+
const tree = fromMarkdown(markdown);
|
|
46
|
+
const images = replaceMarkdownImages(tree, sourcePath);
|
|
47
|
+
if (0 === images.length) return {
|
|
48
|
+
prompt: markdown,
|
|
49
|
+
imageCount: 0
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
prompt: {
|
|
53
|
+
prompt: toMarkdown(tree),
|
|
54
|
+
images,
|
|
55
|
+
convertHttpImage2Base64: true
|
|
56
|
+
},
|
|
57
|
+
imageCount: images.length
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export { markdownToAiActPrompt };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=run-markdown.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent/run-markdown.mjs","sources":["../../../src/agent/run-markdown.ts"],"sourcesContent":["import { dirname, isAbsolute, resolve } from 'node:path';\nimport type { TUserPrompt } from '@/common';\n\nconst MAX_MARKDOWN_IMAGES = 20;\nconst REFERENCE_IMAGE_PREFIX = '参考图片';\n\ntype MdastNode = {\n type: string;\n children?: MdastNode[];\n url?: string;\n identifier?: string;\n label?: string;\n};\n\ntype MdastRoot = MdastNode & {\n children: MdastNode[];\n};\n\ntype MdastFromMarkdownModule = {\n fromMarkdown: (value: string) => MdastRoot;\n};\n\ntype MdastToMarkdownModule = {\n toMarkdown: (tree: MdastRoot) => string;\n};\n\nexport type RunMarkdownTransformResult = {\n prompt: TUserPrompt;\n imageCount: number;\n};\n\nconst imageNameForIndex = (index: number) =>\n `${REFERENCE_IMAGE_PREFIX}-${String(index + 1).padStart(3, '0')}`;\n\nconst formatSource = (sourcePath?: string) =>\n sourcePath ? ` in ${sourcePath}` : '';\n\nconst hasUrlScheme = (url: string) => /^[a-zA-Z][a-zA-Z\\d+.-]*:/.test(url);\n\nconst resolveMarkdownImageUrl = (url: string, sourcePath?: string) => {\n if (!sourcePath || hasUrlScheme(url) || isAbsolute(url)) {\n return url;\n }\n return resolve(dirname(sourcePath), url);\n};\n\nconst replaceMarkdownImages = (tree: MdastRoot, sourcePath?: string) => {\n const images: Array<{ name: string; url: string }> = [];\n\n const visitChildren = (node: MdastNode) => {\n if (!Array.isArray(node.children)) {\n return;\n }\n\n node.children = node.children.map((child) => {\n if (child.type === 'imageReference') {\n const identifier = child.identifier || child.label || 'unknown';\n throw new Error(\n `runMarkdown does not support reference-style image \"${identifier}\"${formatSource(sourcePath)}. Use direct image syntax instead.`,\n );\n }\n\n if (child.type === 'image') {\n const name = imageNameForIndex(images.length);\n if (!child.url) {\n throw new Error(\n `Markdown image ${name}${formatSource(sourcePath)} is missing a URL.`,\n );\n }\n\n images.push({\n name,\n url: resolveMarkdownImageUrl(child.url, sourcePath),\n });\n if (images.length > MAX_MARKDOWN_IMAGES) {\n throw new Error(\n `runMarkdown supports at most ${MAX_MARKDOWN_IMAGES} images, but found ${images.length} images${formatSource(sourcePath)}.`,\n );\n }\n\n return {\n type: 'text',\n value: name,\n } as MdastNode;\n }\n\n visitChildren(child);\n return child;\n });\n };\n\n visitChildren(tree);\n return images;\n};\n\nexport const markdownToAiActPrompt = async (\n markdown: string,\n sourcePath?: string,\n): Promise<RunMarkdownTransformResult> => {\n const fromMarkdownModuleName = 'mdast-util-from-markdown';\n const toMarkdownModuleName = 'mdast-util-to-markdown';\n const { fromMarkdown } = (await import(\n fromMarkdownModuleName\n )) as MdastFromMarkdownModule;\n const { toMarkdown } = (await import(\n toMarkdownModuleName\n )) as MdastToMarkdownModule;\n\n const tree = fromMarkdown(markdown);\n const images = replaceMarkdownImages(tree, sourcePath);\n\n if (images.length === 0) {\n return {\n prompt: markdown,\n imageCount: 0,\n };\n }\n\n return {\n prompt: {\n prompt: toMarkdown(tree),\n images,\n convertHttpImage2Base64: true,\n },\n imageCount: images.length,\n };\n};\n"],"names":["MAX_MARKDOWN_IMAGES","REFERENCE_IMAGE_PREFIX","imageNameForIndex","index","String","formatSource","sourcePath","hasUrlScheme","url","resolveMarkdownImageUrl","isAbsolute","resolve","dirname","replaceMarkdownImages","tree","images","visitChildren","node","Array","child","identifier","Error","name","markdownToAiActPrompt","markdown","fromMarkdownModuleName","toMarkdownModuleName","fromMarkdown","toMarkdown"],"mappings":";AAGA,MAAMA,sBAAsB;AAC5B,MAAMC,yBAAyB;AA2B/B,MAAMC,oBAAoB,CAACC,QACzB,GAAGF,uBAAuB,CAAC,EAAEG,OAAOD,QAAQ,GAAG,QAAQ,CAAC,GAAG,MAAM;AAEnE,MAAME,eAAe,CAACC,aACpBA,aAAa,CAAC,IAAI,EAAEA,YAAY,GAAG;AAErC,MAAMC,eAAe,CAACC,MAAgB,2BAA2B,IAAI,CAACA;AAEtE,MAAMC,0BAA0B,CAACD,KAAaF;IAC5C,IAAI,CAACA,cAAcC,aAAaC,QAAQE,WAAWF,MACjD,OAAOA;IAET,OAAOG,QAAQC,QAAQN,aAAaE;AACtC;AAEA,MAAMK,wBAAwB,CAACC,MAAiBR;IAC9C,MAAMS,SAA+C,EAAE;IAEvD,MAAMC,gBAAgB,CAACC;QACrB,IAAI,CAACC,MAAM,OAAO,CAACD,KAAK,QAAQ,GAC9B;QAGFA,KAAK,QAAQ,GAAGA,KAAK,QAAQ,CAAC,GAAG,CAAC,CAACE;YACjC,IAAIA,AAAe,qBAAfA,MAAM,IAAI,EAAuB;gBACnC,MAAMC,aAAaD,MAAM,UAAU,IAAIA,MAAM,KAAK,IAAI;gBACtD,MAAM,IAAIE,MACR,CAAC,oDAAoD,EAAED,WAAW,CAAC,EAAEf,aAAaC,YAAY,kCAAkC,CAAC;YAErI;YAEA,IAAIa,AAAe,YAAfA,MAAM,IAAI,EAAc;gBAC1B,MAAMG,OAAOpB,kBAAkBa,OAAO,MAAM;gBAC5C,IAAI,CAACI,MAAM,GAAG,EACZ,MAAM,IAAIE,MACR,CAAC,eAAe,EAAEC,OAAOjB,aAAaC,YAAY,kBAAkB,CAAC;gBAIzES,OAAO,IAAI,CAAC;oBACVO;oBACA,KAAKb,wBAAwBU,MAAM,GAAG,EAAEb;gBAC1C;gBACA,IAAIS,OAAO,MAAM,GAAGf,qBAClB,MAAM,IAAIqB,MACR,CAAC,6BAA6B,EAAErB,oBAAoB,mBAAmB,EAAEe,OAAO,MAAM,CAAC,OAAO,EAAEV,aAAaC,YAAY,CAAC,CAAC;gBAI/H,OAAO;oBACL,MAAM;oBACN,OAAOgB;gBACT;YACF;YAEAN,cAAcG;YACd,OAAOA;QACT;IACF;IAEAH,cAAcF;IACd,OAAOC;AACT;AAEO,MAAMQ,wBAAwB,OACnCC,UACAlB;IAEA,MAAMmB,yBAAyB;IAC/B,MAAMC,uBAAuB;IAC7B,MAAM,EAAEC,YAAY,EAAE,GAAI,MAAM,MAAM,CACpCF;IAEF,MAAM,EAAEG,UAAU,EAAE,GAAI,MAAM,MAAM,CAClCF;IAGF,MAAMZ,OAAOa,aAAaH;IAC1B,MAAMT,SAASF,sBAAsBC,MAAMR;IAE3C,IAAIS,AAAkB,MAAlBA,OAAO,MAAM,EACf,OAAO;QACL,QAAQS;QACR,YAAY;IACd;IAGF,OAAO;QACL,QAAQ;YACN,QAAQI,WAAWd;YACnBC;YACA,yBAAyB;QAC3B;QACA,YAAYA,OAAO,MAAM;IAC3B;AACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { convertBase64ImageToJpeg, imageInfoOfBase64, resizeBase64ImageToJpeg } from "@aiscene/shared/img";
|
|
2
|
+
const SCREENSHOT_JPEG_QUALITY = 90;
|
|
3
|
+
function assertValidSize(size, label) {
|
|
4
|
+
if (!Number.isFinite(size.width) || !Number.isFinite(size.height)) throw new Error(`Invalid ${label}: width and height must be finite numbers. Received width: ${size.width}, height: ${size.height}`);
|
|
5
|
+
if (size.width <= 0 || size.height <= 0) throw new Error(`Invalid ${label}: width and height must be positive numbers. Received width: ${size.width}, height: ${size.height}`);
|
|
6
|
+
}
|
|
7
|
+
async function prepareRawScreenshot(screenshotBase64, options) {
|
|
8
|
+
const shrinkFactor = options?.shrinkFactor ?? 1;
|
|
9
|
+
if (!Number.isFinite(shrinkFactor) || shrinkFactor < 1) throw new Error(`Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${shrinkFactor}`);
|
|
10
|
+
const originalSize = await imageInfoOfBase64(screenshotBase64);
|
|
11
|
+
assertValidSize(originalSize, 'screenshot dimensions');
|
|
12
|
+
const shotSize = shrinkFactor > 1 ? {
|
|
13
|
+
width: Math.round(originalSize.width / shrinkFactor),
|
|
14
|
+
height: Math.round(originalSize.height / shrinkFactor)
|
|
15
|
+
} : {
|
|
16
|
+
...originalSize
|
|
17
|
+
};
|
|
18
|
+
assertValidSize(shotSize, 'prepared screenshot dimensions');
|
|
19
|
+
const base64 = await resizeBase64ImageToJpeg(screenshotBase64, {
|
|
20
|
+
sourceSize: originalSize,
|
|
21
|
+
targetSize: shotSize,
|
|
22
|
+
jpegQuality: SCREENSHOT_JPEG_QUALITY
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
base64,
|
|
26
|
+
originalSize,
|
|
27
|
+
shotSize
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function prepareScreenshotForPersistence(screenshotBase64, options) {
|
|
31
|
+
const shrinkFactor = options?.shrinkFactor ?? 1;
|
|
32
|
+
if (1 === shrinkFactor) return convertBase64ImageToJpeg(screenshotBase64, SCREENSHOT_JPEG_QUALITY);
|
|
33
|
+
return (await prepareRawScreenshot(screenshotBase64, options)).base64;
|
|
34
|
+
}
|
|
35
|
+
export { prepareRawScreenshot, prepareScreenshotForPersistence };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=screenshot-preparation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent/screenshot-preparation.mjs","sources":["../../../src/agent/screenshot-preparation.ts"],"sourcesContent":["import {\n type JpegBase64DataUrl,\n convertBase64ImageToJpeg,\n imageInfoOfBase64,\n resizeBase64ImageToJpeg,\n} from '@aiscene/shared/img';\nimport type { Size } from '../types';\n\nconst SCREENSHOT_JPEG_QUALITY = 90;\n\nexport interface PrepareRawScreenshotOptions {\n shrinkFactor?: number;\n}\n\nexport interface PreparedScreenshot {\n base64: JpegBase64DataUrl;\n originalSize: Size;\n shotSize: Size;\n}\n\nfunction assertValidSize(size: Size, label: string): void {\n if (!Number.isFinite(size.width) || !Number.isFinite(size.height)) {\n throw new Error(\n `Invalid ${label}: width and height must be finite numbers. Received width: ${size.width}, height: ${size.height}`,\n );\n }\n if (size.width <= 0 || size.height <= 0) {\n throw new Error(\n `Invalid ${label}: width and height must be positive numbers. Received width: ${size.width}, height: ${size.height}`,\n );\n }\n}\n\n/**\n * Prepare one raw screenshot for model context or observation persistence.\n * Each raw screenshot must pass through this pipeline at most once.\n */\nexport async function prepareRawScreenshot(\n screenshotBase64: string,\n options?: PrepareRawScreenshotOptions,\n): Promise<PreparedScreenshot> {\n const shrinkFactor = options?.shrinkFactor ?? 1;\n if (!Number.isFinite(shrinkFactor) || shrinkFactor < 1) {\n throw new Error(\n `Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${shrinkFactor}`,\n );\n }\n\n const originalSize = await imageInfoOfBase64(screenshotBase64);\n assertValidSize(originalSize, 'screenshot dimensions');\n\n const shotSize =\n shrinkFactor > 1\n ? {\n width: Math.round(originalSize.width / shrinkFactor),\n height: Math.round(originalSize.height / shrinkFactor),\n }\n : { ...originalSize };\n assertValidSize(shotSize, 'prepared screenshot dimensions');\n\n const base64 = await resizeBase64ImageToJpeg(screenshotBase64, {\n sourceSize: originalSize,\n targetSize: shotSize,\n jpegQuality: SCREENSHOT_JPEG_QUALITY,\n });\n\n return {\n base64,\n originalSize,\n shotSize,\n };\n}\n\n/**\n * Prepare a screenshot for persistence when only JPEG output is required.\n * Unscaled frames avoid dimension reads; scaled frames use the full pipeline.\n */\nexport async function prepareScreenshotForPersistence(\n screenshotBase64: string,\n options?: PrepareRawScreenshotOptions,\n): Promise<JpegBase64DataUrl> {\n const shrinkFactor = options?.shrinkFactor ?? 1;\n if (shrinkFactor === 1) {\n return convertBase64ImageToJpeg(screenshotBase64, SCREENSHOT_JPEG_QUALITY);\n }\n return (await prepareRawScreenshot(screenshotBase64, options)).base64;\n}\n"],"names":["SCREENSHOT_JPEG_QUALITY","assertValidSize","size","label","Number","Error","prepareRawScreenshot","screenshotBase64","options","shrinkFactor","originalSize","imageInfoOfBase64","shotSize","Math","base64","resizeBase64ImageToJpeg","prepareScreenshotForPersistence","convertBase64ImageToJpeg"],"mappings":";AAQA,MAAMA,0BAA0B;AAYhC,SAASC,gBAAgBC,IAAU,EAAEC,KAAa;IAChD,IAAI,CAACC,OAAO,QAAQ,CAACF,KAAK,KAAK,KAAK,CAACE,OAAO,QAAQ,CAACF,KAAK,MAAM,GAC9D,MAAM,IAAIG,MACR,CAAC,QAAQ,EAAEF,MAAM,2DAA2D,EAAED,KAAK,KAAK,CAAC,UAAU,EAAEA,KAAK,MAAM,EAAE;IAGtH,IAAIA,KAAK,KAAK,IAAI,KAAKA,KAAK,MAAM,IAAI,GACpC,MAAM,IAAIG,MACR,CAAC,QAAQ,EAAEF,MAAM,6DAA6D,EAAED,KAAK,KAAK,CAAC,UAAU,EAAEA,KAAK,MAAM,EAAE;AAG1H;AAMO,eAAeI,qBACpBC,gBAAwB,EACxBC,OAAqC;IAErC,MAAMC,eAAeD,SAAS,gBAAgB;IAC9C,IAAI,CAACJ,OAAO,QAAQ,CAACK,iBAAiBA,eAAe,GACnD,MAAM,IAAIJ,MACR,CAAC,wEAAwE,EAAEI,cAAc;IAI7F,MAAMC,eAAe,MAAMC,kBAAkBJ;IAC7CN,gBAAgBS,cAAc;IAE9B,MAAME,WACJH,eAAe,IACX;QACE,OAAOI,KAAK,KAAK,CAACH,aAAa,KAAK,GAAGD;QACvC,QAAQI,KAAK,KAAK,CAACH,aAAa,MAAM,GAAGD;IAC3C,IACA;QAAE,GAAGC,YAAY;IAAC;IACxBT,gBAAgBW,UAAU;IAE1B,MAAME,SAAS,MAAMC,wBAAwBR,kBAAkB;QAC7D,YAAYG;QACZ,YAAYE;QACZ,aAAaZ;IACf;IAEA,OAAO;QACLc;QACAJ;QACAE;IACF;AACF;AAMO,eAAeI,gCACpBT,gBAAwB,EACxBC,OAAqC;IAErC,MAAMC,eAAeD,SAAS,gBAAgB;IAC9C,IAAIC,AAAiB,MAAjBA,cACF,OAAOQ,yBAAyBV,kBAAkBP;IAEpD,OAAQ,OAAMM,qBAAqBC,kBAAkBC,QAAO,EAAG,MAAM;AACvE"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { UIObservationRecordWriter, cloneUIObservationRecord } from "@aiscene/shared/agent-tools/observation-record";
|
|
2
|
+
import { getDebug } from "@aiscene/shared/logger";
|
|
3
|
+
import { assert } from "@aiscene/shared/utils";
|
|
4
|
+
import { ScreenshotItem } from "../screenshot-item.mjs";
|
|
5
|
+
import { prepareScreenshotForPersistence } from "./screenshot-preparation.mjs";
|
|
6
|
+
function _define_property(obj, key, value) {
|
|
7
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
8
|
+
value: value,
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true
|
|
12
|
+
});
|
|
13
|
+
else obj[key] = value;
|
|
14
|
+
return obj;
|
|
15
|
+
}
|
|
16
|
+
const debug = getDebug('ui-observer');
|
|
17
|
+
const warnObserver = getDebug('ui-observer', {
|
|
18
|
+
console: true
|
|
19
|
+
});
|
|
20
|
+
const DEFAULT_INTERVAL_MS = 1000;
|
|
21
|
+
const MIN_INTERVAL_MS = 200;
|
|
22
|
+
const DEFAULT_MAX_FRAMES = 30;
|
|
23
|
+
const FIRST_FRAME_TIMEOUT_MS = 3000;
|
|
24
|
+
const DEFAULT_WATCHDOG_MS = 300000;
|
|
25
|
+
const MAX_FRAMES_PER_RECORD = 50;
|
|
26
|
+
const DECODE_BATCH_SIZE = 4;
|
|
27
|
+
class UIObservationImpl {
|
|
28
|
+
get frameCount() {
|
|
29
|
+
return this.record.frames.length;
|
|
30
|
+
}
|
|
31
|
+
get startedAt() {
|
|
32
|
+
return this.record.startedAt;
|
|
33
|
+
}
|
|
34
|
+
get endedAt() {
|
|
35
|
+
return this.record.endedAt;
|
|
36
|
+
}
|
|
37
|
+
ensureUsable() {
|
|
38
|
+
assert(!this.disposed, 'UI observation has been disposed');
|
|
39
|
+
}
|
|
40
|
+
ensureFixedWindowOptions(options) {
|
|
41
|
+
assert(options?.domIncluded === void 0, 'UIObservation does not support domIncluded because it only evaluates recorded screenshots');
|
|
42
|
+
}
|
|
43
|
+
async aiQuery(demand, options) {
|
|
44
|
+
this.ensureUsable();
|
|
45
|
+
this.ensureFixedWindowOptions(options);
|
|
46
|
+
return this.insight.aiQuery(demand, options);
|
|
47
|
+
}
|
|
48
|
+
async aiBoolean(prompt, options) {
|
|
49
|
+
this.ensureUsable();
|
|
50
|
+
this.ensureFixedWindowOptions(options);
|
|
51
|
+
return this.insight.aiBoolean(prompt, options);
|
|
52
|
+
}
|
|
53
|
+
async aiNumber(prompt, options) {
|
|
54
|
+
this.ensureUsable();
|
|
55
|
+
this.ensureFixedWindowOptions(options);
|
|
56
|
+
return this.insight.aiNumber(prompt, options);
|
|
57
|
+
}
|
|
58
|
+
async aiString(prompt, options) {
|
|
59
|
+
this.ensureUsable();
|
|
60
|
+
this.ensureFixedWindowOptions(options);
|
|
61
|
+
return this.insight.aiString(prompt, options);
|
|
62
|
+
}
|
|
63
|
+
async aiAsk(prompt, options) {
|
|
64
|
+
this.ensureUsable();
|
|
65
|
+
this.ensureFixedWindowOptions(options);
|
|
66
|
+
return this.insight.aiAsk(prompt, options);
|
|
67
|
+
}
|
|
68
|
+
async aiAssert(assertion, message, options) {
|
|
69
|
+
this.ensureUsable();
|
|
70
|
+
this.ensureFixedWindowOptions(options);
|
|
71
|
+
return this.insight.aiAssert(assertion, message, options);
|
|
72
|
+
}
|
|
73
|
+
async exportRecord() {
|
|
74
|
+
this.ensureUsable();
|
|
75
|
+
return cloneUIObservationRecord(this.record);
|
|
76
|
+
}
|
|
77
|
+
async dispose() {
|
|
78
|
+
if (this.disposed) return;
|
|
79
|
+
this.disposeRecord?.();
|
|
80
|
+
this.disposed = true;
|
|
81
|
+
this.onDisposed?.();
|
|
82
|
+
}
|
|
83
|
+
constructor(record, insight, disposeRecord, onDisposed){
|
|
84
|
+
_define_property(this, "insight", void 0);
|
|
85
|
+
_define_property(this, "disposeRecord", void 0);
|
|
86
|
+
_define_property(this, "onDisposed", void 0);
|
|
87
|
+
_define_property(this, "disposed", void 0);
|
|
88
|
+
_define_property(this, "record", void 0);
|
|
89
|
+
this.insight = insight;
|
|
90
|
+
this.disposeRecord = disposeRecord;
|
|
91
|
+
this.onDisposed = onDisposed;
|
|
92
|
+
this.disposed = false;
|
|
93
|
+
this.record = cloneUIObservationRecord(record);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function isImageDataUrl(value) {
|
|
97
|
+
return 'string' == typeof value && /^data:image\/(?:png|jpe?g);base64,/i.test(value);
|
|
98
|
+
}
|
|
99
|
+
class UIObserverImpl {
|
|
100
|
+
get bufferedFrameCount() {
|
|
101
|
+
return this.frames.length;
|
|
102
|
+
}
|
|
103
|
+
async start() {
|
|
104
|
+
assert(!this.loopPromise && !this.stopped, 'observer has already started');
|
|
105
|
+
this.startedAt = Date.now();
|
|
106
|
+
try {
|
|
107
|
+
this.source = await this.deps.openFrameSource() ?? null;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
debug(`frame source unavailable, using screenshot fallback: ${error}`);
|
|
110
|
+
this.source = null;
|
|
111
|
+
}
|
|
112
|
+
this.usingFallback = !this.source;
|
|
113
|
+
if (this.usingFallback) debug('no continuous frame source; sampling via plain screenshots');
|
|
114
|
+
else {
|
|
115
|
+
const waitStart = Date.now();
|
|
116
|
+
while(!this.source.latest() && Date.now() - waitStart < FIRST_FRAME_TIMEOUT_MS)await new Promise((resolve)=>setTimeout(resolve, 50));
|
|
117
|
+
if (!this.source.latest()) debug(`no first frame within ${FIRST_FRAME_TIMEOUT_MS}ms; starting anyway`);
|
|
118
|
+
}
|
|
119
|
+
await this.captureOnce();
|
|
120
|
+
this.loopPromise = this.runLoop();
|
|
121
|
+
if (this.watchdogMs > 0) {
|
|
122
|
+
this.watchdogTimer = setTimeout(()=>{
|
|
123
|
+
warnObserver(`UIObserver auto-stopped after ${this.watchdogMs}ms. Call observer.stop() explicitly to avoid this.`);
|
|
124
|
+
this.stop().catch(()=>{});
|
|
125
|
+
}, this.watchdogMs);
|
|
126
|
+
if ('function' == typeof this.watchdogTimer.unref) this.watchdogTimer.unref();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
stop() {
|
|
130
|
+
if (!this.stopPromise) this.stopPromise = this.finalizeStop();
|
|
131
|
+
return this.stopPromise;
|
|
132
|
+
}
|
|
133
|
+
async finalizeStop() {
|
|
134
|
+
this.stopped = true;
|
|
135
|
+
if (this.watchdogTimer) {
|
|
136
|
+
clearTimeout(this.watchdogTimer);
|
|
137
|
+
this.watchdogTimer = null;
|
|
138
|
+
}
|
|
139
|
+
await this.loopPromise;
|
|
140
|
+
try {
|
|
141
|
+
if (this.frames.length > 0) this.persistPromise = this.persistUnstoredFrames().catch((error)=>{
|
|
142
|
+
debug(`frame persistence failed, will retry during export: ${error}`);
|
|
143
|
+
});
|
|
144
|
+
const representativePromise = this.deps.capturePreparedRepresentative();
|
|
145
|
+
const [, representative] = await Promise.all([
|
|
146
|
+
this.persistPromise,
|
|
147
|
+
representativePromise
|
|
148
|
+
]);
|
|
149
|
+
const lastFrame = this.frames.at(-1);
|
|
150
|
+
if (this.source && lastFrame?.persisted) {
|
|
151
|
+
this.representativeFrame = {
|
|
152
|
+
...lastFrame.persisted,
|
|
153
|
+
capturedAt: lastFrame.capturedAt
|
|
154
|
+
};
|
|
155
|
+
representative.screenshot = ScreenshotItem.fromFile(this.writer.resolveFramePath(lastFrame.persisted), lastFrame.persisted.mimeType, lastFrame.capturedAt);
|
|
156
|
+
debug('representative screenshot aligned with last sampled frame');
|
|
157
|
+
}
|
|
158
|
+
this.representative = representative;
|
|
159
|
+
const endedAt = Date.now();
|
|
160
|
+
const record = await this.finalizeRecord(endedAt);
|
|
161
|
+
this.observation = new UIObservationImpl(record, this.deps.createInsight(record), ()=>this.writer.dispose(), this.deps.onDisposed);
|
|
162
|
+
return this.observation;
|
|
163
|
+
} finally{
|
|
164
|
+
if (this.source) try {
|
|
165
|
+
await this.source.stop();
|
|
166
|
+
} catch (error) {
|
|
167
|
+
debug(`error stopping frame source: ${error}`);
|
|
168
|
+
}
|
|
169
|
+
debug(`observation stopped with ${this.frames.length} buffered frames (+1 representative)`);
|
|
170
|
+
this.deps.onStopped?.();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async finalizeRecord(endedAt) {
|
|
174
|
+
assert(this.stopped && this.representative, 'observation must be stopped before finalizing the observed window');
|
|
175
|
+
if (this.persistPromise) {
|
|
176
|
+
await this.persistPromise;
|
|
177
|
+
this.persistPromise = null;
|
|
178
|
+
}
|
|
179
|
+
await this.persistUnstoredFrames();
|
|
180
|
+
const sampledFrames = this.frames.map((frame)=>{
|
|
181
|
+
assert(frame.persisted, 'observation frame was not persisted');
|
|
182
|
+
return {
|
|
183
|
+
...frame.persisted,
|
|
184
|
+
capturedAt: frame.capturedAt
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
if (!this.representativeFrame) {
|
|
188
|
+
const representative = this.representative;
|
|
189
|
+
this.representativeFrame = this.writer.persistFrame(representative.screenshot.base64, representative.screenshot.capturedAt);
|
|
190
|
+
representative.screenshot = ScreenshotItem.fromFile(this.writer.resolveFramePath(this.representativeFrame), this.representativeFrame.mimeType, this.representativeFrame.capturedAt);
|
|
191
|
+
}
|
|
192
|
+
const frames = [
|
|
193
|
+
...sampledFrames,
|
|
194
|
+
this.representativeFrame
|
|
195
|
+
];
|
|
196
|
+
if (frames.length > MAX_FRAMES_PER_RECORD) warnObserver(`WARNING: exporting ${frames.length} frames (soft limit ${MAX_FRAMES_PER_RECORD}). Running insight against this observation sends every frame to the model; consider increasing intervalMs or decreasing maxFrames to reduce token cost.`);
|
|
197
|
+
debug(`exporting ${frames.length} file-backed observation frames (${this.persistedByRef.size} decoded source refs)`);
|
|
198
|
+
const metadata = {
|
|
199
|
+
startedAt: this.startedAt,
|
|
200
|
+
endedAt,
|
|
201
|
+
shotSize: {
|
|
202
|
+
...this.representative.shotSize
|
|
203
|
+
},
|
|
204
|
+
shrunkShotToLogicalRatio: this.representative.shrunkShotToLogicalRatio
|
|
205
|
+
};
|
|
206
|
+
return this.writer.finalize(frames, metadata);
|
|
207
|
+
}
|
|
208
|
+
async dispose() {
|
|
209
|
+
if (this.disposed) return;
|
|
210
|
+
try {
|
|
211
|
+
if (this.stopPromise) await this.stopPromise;
|
|
212
|
+
else if (!this.stopped) await this.stop();
|
|
213
|
+
} finally{
|
|
214
|
+
if (this.observation) await this.observation.dispose();
|
|
215
|
+
else {
|
|
216
|
+
this.writer.dispose();
|
|
217
|
+
this.deps.onDisposed?.();
|
|
218
|
+
}
|
|
219
|
+
this.frames = [];
|
|
220
|
+
this.persistedByRef.clear();
|
|
221
|
+
this.observation = null;
|
|
222
|
+
this.disposed = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async persistUnstoredFrames() {
|
|
226
|
+
const uniqueFrames = this.dedupeRefs(this.frames.filter((frame)=>!frame.persisted));
|
|
227
|
+
const uncachedFrames = uniqueFrames.filter((frame)=>!this.persistedByRef.has(frame.ref));
|
|
228
|
+
for(let start = 0; start < uncachedFrames.length; start += DECODE_BATCH_SIZE){
|
|
229
|
+
const batch = uncachedFrames.slice(start, start + DECODE_BATCH_SIZE);
|
|
230
|
+
const decoded = this.source ? await this.source.decode(batch) : batch.map((frame)=>{
|
|
231
|
+
assert(isImageDataUrl(frame.ref), 'fallback observation frame must be an image data URL');
|
|
232
|
+
return frame.ref;
|
|
233
|
+
});
|
|
234
|
+
assert(decoded.length === batch.length, 'frame source decode() must return one image per frame handle');
|
|
235
|
+
const preparedDataUrls = await Promise.all(decoded.map((dataUrl)=>prepareScreenshotForPersistence(dataUrl, {
|
|
236
|
+
shrinkFactor: this.screenshotShrinkFactor
|
|
237
|
+
})));
|
|
238
|
+
for(let index = 0; index < batch.length; index++)this.persistedByRef.set(batch[index].ref, this.writer.persistFrame(preparedDataUrls[index], batch[index].capturedAt));
|
|
239
|
+
}
|
|
240
|
+
for (const frame of this.frames)frame.persisted ??= this.persistedByRef.get(frame.ref);
|
|
241
|
+
if (uncachedFrames.length > 0) debug(`decoded and persisted ${uncachedFrames.length} source frames`);
|
|
242
|
+
}
|
|
243
|
+
async captureOnce() {
|
|
244
|
+
try {
|
|
245
|
+
if (this.source) {
|
|
246
|
+
const frame = this.source.latest();
|
|
247
|
+
if (!frame) return;
|
|
248
|
+
if (isImageDataUrl(frame.ref)) {
|
|
249
|
+
const preparedDataUrl = await prepareScreenshotForPersistence(frame.ref, {
|
|
250
|
+
shrinkFactor: this.screenshotShrinkFactor
|
|
251
|
+
});
|
|
252
|
+
const persisted = this.writer.persistFrame(preparedDataUrl, frame.capturedAt);
|
|
253
|
+
this.pushFrame({
|
|
254
|
+
ref: persisted.path,
|
|
255
|
+
capturedAt: frame.capturedAt,
|
|
256
|
+
persisted
|
|
257
|
+
});
|
|
258
|
+
} else this.pushFrame(frame);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const preparedDataUrl = await prepareScreenshotForPersistence(await this.deps.captureRawScreenshot(), {
|
|
262
|
+
shrinkFactor: this.screenshotShrinkFactor
|
|
263
|
+
});
|
|
264
|
+
const persisted = this.writer.persistFrame(preparedDataUrl, Date.now());
|
|
265
|
+
this.pushFrame({
|
|
266
|
+
ref: persisted.path,
|
|
267
|
+
capturedAt: persisted.capturedAt,
|
|
268
|
+
persisted
|
|
269
|
+
});
|
|
270
|
+
} catch (error) {
|
|
271
|
+
debug(`frame capture failed, skipping tick: ${error}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async runLoop() {
|
|
275
|
+
while(!this.stopped){
|
|
276
|
+
const tickStart = Date.now();
|
|
277
|
+
await this.captureOnce();
|
|
278
|
+
while(!this.stopped && Date.now() - tickStart < this.intervalMs)await new Promise((resolve)=>setTimeout(resolve, 50));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
pushFrame(frame) {
|
|
282
|
+
this.frames.push(frame);
|
|
283
|
+
if (this.frames.length > this.maxFrames) {
|
|
284
|
+
this.frames = this.thinBuffer(this.frames);
|
|
285
|
+
this.writer.pruneFrames(this.frames.flatMap((retainedFrame)=>retainedFrame.persisted ? [
|
|
286
|
+
retainedFrame.persisted
|
|
287
|
+
] : []));
|
|
288
|
+
debug(`frame buffer thinned to ${this.frames.length} frames`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
thinBuffer(frames) {
|
|
292
|
+
if (frames.length <= 1) return frames;
|
|
293
|
+
const isChangePoint = new Array(frames.length).fill(false);
|
|
294
|
+
isChangePoint[0] = true;
|
|
295
|
+
for(let index = 1; index < frames.length; index++)if (frames[index].ref !== frames[index - 1].ref) isChangePoint[index] = true;
|
|
296
|
+
isChangePoint[frames.length - 1] = true;
|
|
297
|
+
let result = [];
|
|
298
|
+
let staticCounter = 0;
|
|
299
|
+
for(let index = 0; index < frames.length; index++)if (isChangePoint[index]) {
|
|
300
|
+
result.push(frames[index]);
|
|
301
|
+
staticCounter = 0;
|
|
302
|
+
} else if (staticCounter % 2 === 0) {
|
|
303
|
+
result.push(frames[index]);
|
|
304
|
+
staticCounter++;
|
|
305
|
+
} else staticCounter++;
|
|
306
|
+
if (result.length > this.maxFrames) {
|
|
307
|
+
const step = result.length / this.maxFrames;
|
|
308
|
+
const sampled = [];
|
|
309
|
+
for(let index = 0; index < this.maxFrames; index++)sampled.push(result[Math.floor(index * step)]);
|
|
310
|
+
sampled[this.maxFrames - 1] = result[result.length - 1];
|
|
311
|
+
result = sampled;
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
dedupeRefs(frames) {
|
|
316
|
+
const seen = new Set();
|
|
317
|
+
const result = [];
|
|
318
|
+
for (const frame of frames)if (!seen.has(frame.ref)) {
|
|
319
|
+
seen.add(frame.ref);
|
|
320
|
+
result.push(frame);
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
constructor(deps, opt){
|
|
325
|
+
_define_property(this, "deps", void 0);
|
|
326
|
+
_define_property(this, "frames", void 0);
|
|
327
|
+
_define_property(this, "source", void 0);
|
|
328
|
+
_define_property(this, "usingFallback", void 0);
|
|
329
|
+
_define_property(this, "stopped", void 0);
|
|
330
|
+
_define_property(this, "disposed", void 0);
|
|
331
|
+
_define_property(this, "loopPromise", void 0);
|
|
332
|
+
_define_property(this, "stopPromise", void 0);
|
|
333
|
+
_define_property(this, "representative", void 0);
|
|
334
|
+
_define_property(this, "representativeFrame", void 0);
|
|
335
|
+
_define_property(this, "watchdogTimer", void 0);
|
|
336
|
+
_define_property(this, "persistPromise", void 0);
|
|
337
|
+
_define_property(this, "persistedByRef", void 0);
|
|
338
|
+
_define_property(this, "observation", void 0);
|
|
339
|
+
_define_property(this, "startedAt", void 0);
|
|
340
|
+
_define_property(this, "intervalMs", void 0);
|
|
341
|
+
_define_property(this, "maxFrames", void 0);
|
|
342
|
+
_define_property(this, "watchdogMs", void 0);
|
|
343
|
+
_define_property(this, "screenshotShrinkFactor", void 0);
|
|
344
|
+
_define_property(this, "writer", void 0);
|
|
345
|
+
this.deps = deps;
|
|
346
|
+
this.frames = [];
|
|
347
|
+
this.source = null;
|
|
348
|
+
this.usingFallback = false;
|
|
349
|
+
this.stopped = false;
|
|
350
|
+
this.disposed = false;
|
|
351
|
+
this.loopPromise = null;
|
|
352
|
+
this.stopPromise = null;
|
|
353
|
+
this.representative = null;
|
|
354
|
+
this.representativeFrame = null;
|
|
355
|
+
this.watchdogTimer = null;
|
|
356
|
+
this.persistPromise = null;
|
|
357
|
+
this.persistedByRef = new Map();
|
|
358
|
+
this.observation = null;
|
|
359
|
+
this.startedAt = 0;
|
|
360
|
+
this.intervalMs = Math.max(MIN_INTERVAL_MS, opt?.intervalMs ?? DEFAULT_INTERVAL_MS);
|
|
361
|
+
this.maxFrames = Math.max(2, opt?.maxFrames ?? DEFAULT_MAX_FRAMES);
|
|
362
|
+
this.watchdogMs = opt?.watchdogMs ?? DEFAULT_WATCHDOG_MS;
|
|
363
|
+
this.screenshotShrinkFactor = deps.screenshotShrinkFactor ?? 1;
|
|
364
|
+
this.writer = deps.observationRecordWriter ?? new UIObservationRecordWriter();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
function uiContextFromObservationRecord(record) {
|
|
368
|
+
assert('midscene_ui_observation' === record.type && 1 === record.version, 'invalid UI observation record type or version');
|
|
369
|
+
assert(record.frames.length > 0, 'UI observation record contains no frames');
|
|
370
|
+
assert(Number.isFinite(record.shotSize.width) && record.shotSize.width > 0, 'UI observation record shot width must be positive');
|
|
371
|
+
assert(Number.isFinite(record.shotSize.height) && record.shotSize.height > 0, 'UI observation record shot height must be positive');
|
|
372
|
+
assert(Number.isFinite(record.shrunkShotToLogicalRatio) && record.shrunkShotToLogicalRatio > 0, 'UI observation record screenshot ratio must be positive');
|
|
373
|
+
const screenshotSequence = record.frames.map((frame)=>ScreenshotItem.fromFile(frame.path, frame.mimeType, frame.capturedAt));
|
|
374
|
+
return {
|
|
375
|
+
screenshot: screenshotSequence[screenshotSequence.length - 1],
|
|
376
|
+
screenshotSequence,
|
|
377
|
+
shotSize: {
|
|
378
|
+
...record.shotSize
|
|
379
|
+
},
|
|
380
|
+
shrunkShotToLogicalRatio: record.shrunkShotToLogicalRatio
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
export { UIObservationImpl, UIObserverImpl, uiContextFromObservationRecord };
|
|
384
|
+
|
|
385
|
+
//# sourceMappingURL=ui-observer.mjs.map
|