flow-frame-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/dist/Dockerfile +86 -0
- package/dist/GPU_DEPLOYMENT_README.md +324 -0
- package/dist/OPS_AGENT_README.md +174 -0
- package/dist/README-H100-VM.md +192 -0
- package/dist/README-worker-pools.md +231 -0
- package/dist/README.md +8 -0
- package/dist/WEB-ELEMENT-REQUESTS-README.md +302 -0
- package/dist/append.d.ts +3 -0
- package/dist/append.d.ts.map +1 -0
- package/dist/append.js +42 -0
- package/dist/append.js.map +1 -0
- package/dist/audioRoutes.d.ts +2 -0
- package/dist/audioRoutes.d.ts.map +1 -0
- package/dist/audioRoutes.js +97 -0
- package/dist/audioRoutes.js.map +1 -0
- package/dist/augment-parallel.d.ts +6 -0
- package/dist/augment-parallel.d.ts.map +1 -0
- package/dist/augment-parallel.js +128 -0
- package/dist/augment-parallel.js.map +1 -0
- package/dist/augment-worker.d.ts +2 -0
- package/dist/augment-worker.d.ts.map +1 -0
- package/dist/augment-worker.js +100 -0
- package/dist/augment-worker.js.map +1 -0
- package/dist/browerRoutes.d.ts +2 -0
- package/dist/browerRoutes.d.ts.map +1 -0
- package/dist/browerRoutes.js +323 -0
- package/dist/browerRoutes.js.map +1 -0
- package/dist/browser-utils/utils.d.ts +6 -0
- package/dist/browser-utils/utils.d.ts.map +1 -0
- package/dist/browser-utils/utils.js +133 -0
- package/dist/browser-utils/utils.js.map +1 -0
- package/dist/capture_training_data_endpoints.d.ts +158 -0
- package/dist/capture_training_data_endpoints.d.ts.map +1 -0
- package/dist/capture_training_data_endpoints.js +1812 -0
- package/dist/capture_training_data_endpoints.js.map +1 -0
- package/dist/config.json +28 -0
- package/dist/configEndpoints.d.ts +2 -0
- package/dist/configEndpoints.d.ts.map +1 -0
- package/dist/configEndpoints.js +459 -0
- package/dist/configEndpoints.js.map +1 -0
- package/dist/constants.d.ts +109 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +110 -0
- package/dist/constants.js.map +1 -0
- package/dist/docs/workflow_nodes.md +257 -0
- package/dist/download.d.ts +11 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +31 -0
- package/dist/download.js.map +1 -0
- package/dist/download.py +61 -0
- package/dist/ecosystem.config.json +63 -0
- package/dist/email-body-extractor.d.ts +20 -0
- package/dist/email-body-extractor.d.ts.map +1 -0
- package/dist/email-body-extractor.js +103 -0
- package/dist/email-body-extractor.js.map +1 -0
- package/dist/express_util.d.ts +2 -0
- package/dist/express_util.d.ts.map +1 -0
- package/dist/express_util.js +30 -0
- package/dist/express_util.js.map +1 -0
- package/dist/extension/background.d.ts +2 -0
- package/dist/extension/background.d.ts.map +1 -0
- package/dist/extension/background.js +268 -0
- package/dist/extension/background.js.map +1 -0
- package/dist/extension/manifest.json +19 -0
- package/dist/extensionUtils.d.ts +2 -0
- package/dist/extensionUtils.d.ts.map +1 -0
- package/dist/extensionUtils.js +48 -0
- package/dist/extensionUtils.js.map +1 -0
- package/dist/filter-gmail-poller/README.md +320 -0
- package/dist/filter-gmail-poller/demo.d.ts +2 -0
- package/dist/filter-gmail-poller/demo.d.ts.map +1 -0
- package/dist/filter-gmail-poller/demo.js +79 -0
- package/dist/filter-gmail-poller/demo.js.map +1 -0
- package/dist/filter-gmail-poller/example-existing-app.d.ts +2 -0
- package/dist/filter-gmail-poller/example-existing-app.d.ts.map +1 -0
- package/dist/filter-gmail-poller/example-existing-app.js +72 -0
- package/dist/filter-gmail-poller/example-existing-app.js.map +1 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.d.ts +160 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.d.ts.map +1 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.js +1048 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.js.map +1 -0
- package/dist/filter-gmail-poller/index.d.ts +3 -0
- package/dist/filter-gmail-poller/index.d.ts.map +1 -0
- package/dist/filter-gmail-poller/index.js +18 -0
- package/dist/filter-gmail-poller/index.js.map +1 -0
- package/dist/filter-gmail-poller/manual-test.d.ts +2 -0
- package/dist/filter-gmail-poller/manual-test.d.ts.map +1 -0
- package/dist/filter-gmail-poller/manual-test.js +70 -0
- package/dist/filter-gmail-poller/manual-test.js.map +1 -0
- package/dist/filter-gmail-poller/poller-prompts.d.ts +12 -0
- package/dist/filter-gmail-poller/poller-prompts.d.ts.map +1 -0
- package/dist/filter-gmail-poller/poller-prompts.js +330 -0
- package/dist/filter-gmail-poller/poller-prompts.js.map +1 -0
- package/dist/filter-gmail-poller/test.js +69 -0
- package/dist/flowframe-auto-firebase-adminsdk.json +13 -0
- package/dist/gmail-poller/README-microsoft-email-poller.md +203 -0
- package/dist/gmail-poller/README.md +129 -0
- package/dist/gmail-poller/example.d.ts +5 -0
- package/dist/gmail-poller/example.d.ts.map +1 -0
- package/dist/gmail-poller/example.js +83 -0
- package/dist/gmail-poller/example.js.map +1 -0
- package/dist/gmail-poller/gmail-poller.d.ts +82 -0
- package/dist/gmail-poller/gmail-poller.d.ts.map +1 -0
- package/dist/gmail-poller/gmail-poller.js +455 -0
- package/dist/gmail-poller/gmail-poller.js.map +1 -0
- package/dist/gmail-poller/manual-test.d.ts +2 -0
- package/dist/gmail-poller/manual-test.d.ts.map +1 -0
- package/dist/gmail-poller/manual-test.js +37 -0
- package/dist/gmail-poller/manual-test.js.map +1 -0
- package/dist/gmail-poller/microsoft-email-example.d.ts +8 -0
- package/dist/gmail-poller/microsoft-email-example.d.ts.map +1 -0
- package/dist/gmail-poller/microsoft-email-example.js +58 -0
- package/dist/gmail-poller/microsoft-email-example.js.map +1 -0
- package/dist/gmail-poller/microsoft-email-poller.d.ts +73 -0
- package/dist/gmail-poller/microsoft-email-poller.d.ts.map +1 -0
- package/dist/gmail-poller/microsoft-email-poller.js +346 -0
- package/dist/gmail-poller/microsoft-email-poller.js.map +1 -0
- package/dist/gmail-poller/setup-auth.d.ts +3 -0
- package/dist/gmail-poller/setup-auth.d.ts.map +1 -0
- package/dist/gmail-poller/setup-auth.js +36 -0
- package/dist/gmail-poller/setup-auth.js.map +1 -0
- package/dist/gmail-poller/test.js +36 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/inference/augment_levels.d.ts +2 -0
- package/dist/inference/augment_levels.d.ts.map +1 -0
- package/dist/inference/augment_levels.js +1 -0
- package/dist/inference/augment_levels.js.map +1 -0
- package/dist/inference/capture-overlay.d.ts +13 -0
- package/dist/inference/capture-overlay.d.ts.map +1 -0
- package/dist/inference/capture-overlay.js +355 -0
- package/dist/inference/capture-overlay.js.map +1 -0
- package/dist/inference/capturescreenshot.d.ts +12 -0
- package/dist/inference/capturescreenshot.d.ts.map +1 -0
- package/dist/inference/capturescreenshot.js +157 -0
- package/dist/inference/capturescreenshot.js.map +1 -0
- package/dist/jsonHandler.d.ts +37 -0
- package/dist/jsonHandler.d.ts.map +1 -0
- package/dist/jsonHandler.js +191 -0
- package/dist/jsonHandler.js.map +1 -0
- package/dist/localStorage.json +11 -0
- package/dist/media_data_endpoints.d.ts +2 -0
- package/dist/media_data_endpoints.d.ts.map +1 -0
- package/dist/media_data_endpoints.js +102 -0
- package/dist/media_data_endpoints.js.map +1 -0
- package/dist/operations/blender-ops.d.ts +4 -0
- package/dist/operations/blender-ops.d.ts.map +1 -0
- package/dist/operations/blender-ops.js +55 -0
- package/dist/operations/blender-ops.js.map +1 -0
- package/dist/operations.d.ts +34 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +1514 -0
- package/dist/operations.js.map +1 -0
- package/dist/pdfRoutes.d.ts +2 -0
- package/dist/pdfRoutes.d.ts.map +1 -0
- package/dist/pdfRoutes.js +56 -0
- package/dist/pdfRoutes.js.map +1 -0
- package/dist/peers.d.ts +9 -0
- package/dist/peers.d.ts.map +1 -0
- package/dist/peers.js +70 -0
- package/dist/peers.js.map +1 -0
- package/dist/playparser.d.ts +2 -0
- package/dist/playparser.d.ts.map +1 -0
- package/dist/playparser.js +281 -0
- package/dist/playparser.js.map +1 -0
- package/dist/process.d.ts +4 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +375 -0
- package/dist/process.js.map +1 -0
- package/dist/promptRoutes.d.ts +7 -0
- package/dist/promptRoutes.d.ts.map +1 -0
- package/dist/promptRoutes.js +68 -0
- package/dist/promptRoutes.js.map +1 -0
- package/dist/queueManager.d.ts +23 -0
- package/dist/queueManager.d.ts.map +1 -0
- package/dist/queueManager.js +96 -0
- package/dist/queueManager.js.map +1 -0
- package/dist/run-flow.d.ts +8 -0
- package/dist/run-flow.d.ts.map +1 -0
- package/dist/run-flow.js +220 -0
- package/dist/run-flow.js.map +1 -0
- package/dist/scraper.d.ts +2 -0
- package/dist/scraper.d.ts.map +1 -0
- package/dist/scraper.js +75 -0
- package/dist/scraper.js.map +1 -0
- package/dist/scraper_endpoints.d.ts +2 -0
- package/dist/scraper_endpoints.d.ts.map +1 -0
- package/dist/scraper_endpoints.js +40 -0
- package/dist/scraper_endpoints.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +528 -0
- package/dist/server.js.map +1 -0
- package/dist/services/ModelContext.d.ts +7 -0
- package/dist/services/ModelContext.d.ts.map +1 -0
- package/dist/services/ModelContext.js +7 -0
- package/dist/services/ModelContext.js.map +1 -0
- package/dist/services/agenticUiPlanner.d.ts +27 -0
- package/dist/services/agenticUiPlanner.d.ts.map +1 -0
- package/dist/services/agenticUiPlanner.js +161 -0
- package/dist/services/agenticUiPlanner.js.map +1 -0
- package/dist/services/apiKeyService.d.ts +3 -0
- package/dist/services/apiKeyService.d.ts.map +1 -0
- package/dist/services/apiKeyService.js +7 -0
- package/dist/services/apiKeyService.js.map +1 -0
- package/dist/services/audioService.d.ts +10 -0
- package/dist/services/audioService.d.ts.map +1 -0
- package/dist/services/audioService.js +140 -0
- package/dist/services/audioService.js.map +1 -0
- package/dist/services/autoPromptOptimizer.d.ts +44 -0
- package/dist/services/autoPromptOptimizer.d.ts.map +1 -0
- package/dist/services/autoPromptOptimizer.js +344 -0
- package/dist/services/autoPromptOptimizer.js.map +1 -0
- package/dist/services/autoPromptOptimizer.manual-test.d.ts +2 -0
- package/dist/services/autoPromptOptimizer.manual-test.d.ts.map +1 -0
- package/dist/services/autoPromptOptimizer.manual-test.js +27 -0
- package/dist/services/autoPromptOptimizer.manual-test.js.map +1 -0
- package/dist/services/chainExecutor.d.ts +26 -0
- package/dist/services/chainExecutor.d.ts.map +1 -0
- package/dist/services/chainExecutor.js +399 -0
- package/dist/services/chainExecutor.js.map +1 -0
- package/dist/services/classifyImageQuestion.d.ts +55 -0
- package/dist/services/classifyImageQuestion.d.ts.map +1 -0
- package/dist/services/classifyImageQuestion.js +428 -0
- package/dist/services/classifyImageQuestion.js.map +1 -0
- package/dist/services/configuration/executor.d.ts +3 -0
- package/dist/services/configuration/executor.d.ts.map +1 -0
- package/dist/services/configuration/executor.js +795 -0
- package/dist/services/configuration/executor.js.map +1 -0
- package/dist/services/error.d.ts +13 -0
- package/dist/services/error.d.ts.map +1 -0
- package/dist/services/error.js +34 -0
- package/dist/services/error.js.map +1 -0
- package/dist/services/executor.d.ts +11 -0
- package/dist/services/executor.d.ts.map +1 -0
- package/dist/services/executor.js +1587 -0
- package/dist/services/executor.js.map +1 -0
- package/dist/services/extractPdf.d.ts +26 -0
- package/dist/services/extractPdf.d.ts.map +1 -0
- package/dist/services/extractPdf.js +256 -0
- package/dist/services/extractPdf.js.map +1 -0
- package/dist/services/generateJsTransformFromPrompt.d.ts +11 -0
- package/dist/services/generateJsTransformFromPrompt.d.ts.map +1 -0
- package/dist/services/generateJsTransformFromPrompt.js +328 -0
- package/dist/services/generateJsTransformFromPrompt.js.map +1 -0
- package/dist/services/localizeFirebaseMedia.d.ts +20 -0
- package/dist/services/localizeFirebaseMedia.d.ts.map +1 -0
- package/dist/services/localizeFirebaseMedia.js +135 -0
- package/dist/services/localizeFirebaseMedia.js.map +1 -0
- package/dist/services/polyfill_canvas.d.ts +2 -0
- package/dist/services/polyfill_canvas.d.ts.map +1 -0
- package/dist/services/polyfill_canvas.js +19 -0
- package/dist/services/polyfill_canvas.js.map +1 -0
- package/dist/services/promptRoutes.d.ts +7 -0
- package/dist/services/promptRoutes.d.ts.map +1 -0
- package/dist/services/promptRoutes.js +70 -0
- package/dist/services/promptRoutes.js.map +1 -0
- package/dist/services/runPrompt.d.ts +29 -0
- package/dist/services/runPrompt.d.ts.map +1 -0
- package/dist/services/runPrompt.js +232 -0
- package/dist/services/runPrompt.js.map +1 -0
- package/dist/services/schemaInference.d.ts +2 -0
- package/dist/services/schemaInference.d.ts.map +1 -0
- package/dist/services/schemaInference.js +17 -0
- package/dist/services/schemaInference.js.map +1 -0
- package/dist/services/self-learning/api.d.ts +2 -0
- package/dist/services/self-learning/api.d.ts.map +1 -0
- package/dist/services/self-learning/api.js +84 -0
- package/dist/services/self-learning/api.js.map +1 -0
- package/dist/services/self-learning/autolearn.d.ts +23 -0
- package/dist/services/self-learning/autolearn.d.ts.map +1 -0
- package/dist/services/self-learning/autolearn.js +308 -0
- package/dist/services/self-learning/autolearn.js.map +1 -0
- package/dist/services/self-learning/discover.d.ts +11 -0
- package/dist/services/self-learning/discover.d.ts.map +1 -0
- package/dist/services/self-learning/discover.js +446 -0
- package/dist/services/self-learning/discover.js.map +1 -0
- package/dist/services/self-learning/image.d.ts +10 -0
- package/dist/services/self-learning/image.d.ts.map +1 -0
- package/dist/services/self-learning/image.js +38 -0
- package/dist/services/self-learning/image.js.map +1 -0
- package/dist/services/self-learning/injest.d.ts +25 -0
- package/dist/services/self-learning/injest.d.ts.map +1 -0
- package/dist/services/self-learning/injest.js +110 -0
- package/dist/services/self-learning/injest.js.map +1 -0
- package/dist/services/self-learning/learn.d.ts +2 -0
- package/dist/services/self-learning/learn.d.ts.map +1 -0
- package/dist/services/self-learning/learn.js +145 -0
- package/dist/services/self-learning/learn.js.map +1 -0
- package/dist/services/self-learning/matcher.d.ts +2 -0
- package/dist/services/self-learning/matcher.d.ts.map +1 -0
- package/dist/services/self-learning/matcher.js +38 -0
- package/dist/services/self-learning/matcher.js.map +1 -0
- package/dist/services/self-learning/openai.d.ts +8 -0
- package/dist/services/self-learning/openai.d.ts.map +1 -0
- package/dist/services/self-learning/openai.js +97 -0
- package/dist/services/self-learning/openai.js.map +1 -0
- package/dist/services/self-learning/phash.d.ts +5 -0
- package/dist/services/self-learning/phash.d.ts.map +1 -0
- package/dist/services/self-learning/phash.js +68 -0
- package/dist/services/self-learning/phash.js.map +1 -0
- package/dist/services/self-learning/recognize.d.ts +17 -0
- package/dist/services/self-learning/recognize.d.ts.map +1 -0
- package/dist/services/self-learning/recognize.js +116 -0
- package/dist/services/self-learning/recognize.js.map +1 -0
- package/dist/services/self-learning/record_transition.d.ts +8 -0
- package/dist/services/self-learning/record_transition.d.ts.map +1 -0
- package/dist/services/self-learning/record_transition.js +20 -0
- package/dist/services/self-learning/record_transition.js.map +1 -0
- package/dist/services/self-learning/registry.d.ts +4 -0
- package/dist/services/self-learning/registry.d.ts.map +1 -0
- package/dist/services/self-learning/registry.js +19 -0
- package/dist/services/self-learning/registry.js.map +1 -0
- package/dist/services/self-learning/schema.d.ts +114 -0
- package/dist/services/self-learning/schema.d.ts.map +1 -0
- package/dist/services/self-learning/schema.js +70 -0
- package/dist/services/self-learning/schema.js.map +1 -0
- package/dist/services/self-learning/schemaStrictify.d.ts +2 -0
- package/dist/services/self-learning/schemaStrictify.d.ts.map +1 -0
- package/dist/services/self-learning/schemaStrictify.js +34 -0
- package/dist/services/self-learning/schemaStrictify.js.map +1 -0
- package/dist/services/self-learning/transition_graph.d.ts +6 -0
- package/dist/services/self-learning/transition_graph.d.ts.map +1 -0
- package/dist/services/self-learning/transition_graph.js +83 -0
- package/dist/services/self-learning/transition_graph.js.map +1 -0
- package/dist/services/self-learning/transition_log.d.ts +3 -0
- package/dist/services/self-learning/transition_log.d.ts.map +1 -0
- package/dist/services/self-learning/transition_log.js +42 -0
- package/dist/services/self-learning/transition_log.js.map +1 -0
- package/dist/services/self-learning/util.d.ts +3 -0
- package/dist/services/self-learning/util.d.ts.map +1 -0
- package/dist/services/self-learning/util.js +11 -0
- package/dist/services/self-learning/util.js.map +1 -0
- package/dist/services/stepByStepAiPlanner.d.ts +39 -0
- package/dist/services/stepByStepAiPlanner.d.ts.map +1 -0
- package/dist/services/stepByStepAiPlanner.js +379 -0
- package/dist/services/stepByStepAiPlanner.js.map +1 -0
- package/dist/services/test-genjs.js +39 -0
- package/dist/services/test-genjs.manual-test.d.ts +2 -0
- package/dist/services/test-genjs.manual-test.d.ts.map +1 -0
- package/dist/services/test-genjs.manual-test.js +40 -0
- package/dist/services/test-genjs.manual-test.js.map +1 -0
- package/dist/services/uiMapPathFinder.d.ts +13 -0
- package/dist/services/uiMapPathFinder.d.ts.map +1 -0
- package/dist/services/uiMapPathFinder.js +79 -0
- package/dist/services/uiMapPathFinder.js.map +1 -0
- package/dist/services/uiMapService.d.ts +26 -0
- package/dist/services/uiMapService.d.ts.map +1 -0
- package/dist/services/uiMapService.js +275 -0
- package/dist/services/uiMapService.js.map +1 -0
- package/dist/services/uiPlanner.d.ts +54 -0
- package/dist/services/uiPlanner.d.ts.map +1 -0
- package/dist/services/uiPlanner.js +558 -0
- package/dist/services/uiPlanner.js.map +1 -0
- package/dist/services/utilityFunctions.d.ts +80 -0
- package/dist/services/utilityFunctions.d.ts.map +1 -0
- package/dist/services/utilityFunctions.js +352 -0
- package/dist/services/utilityFunctions.js.map +1 -0
- package/dist/services/variableGenerator.d.ts +39 -0
- package/dist/services/variableGenerator.d.ts.map +1 -0
- package/dist/services/variableGenerator.js +157 -0
- package/dist/services/variableGenerator.js.map +1 -0
- package/dist/services/workflow/build-workflow.d.ts +49 -0
- package/dist/services/workflow/build-workflow.d.ts.map +1 -0
- package/dist/services/workflow/build-workflow.js +119 -0
- package/dist/services/workflow/build-workflow.js.map +1 -0
- package/dist/standardRoutes.d.ts +2 -0
- package/dist/standardRoutes.d.ts.map +1 -0
- package/dist/standardRoutes.js +1495 -0
- package/dist/standardRoutes.js.map +1 -0
- package/dist/stepWorkflowRoutes.d.ts +2 -0
- package/dist/stepWorkflowRoutes.d.ts.map +1 -0
- package/dist/stepWorkflowRoutes.js +1007 -0
- package/dist/stepWorkflowRoutes.js.map +1 -0
- package/dist/storage.d.ts +19 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.docker.json +61 -0
- package/dist/storage.js +131 -0
- package/dist/storage.js.map +1 -0
- package/dist/storage.json +78 -0
- package/dist/storage_cache/boxes.json +48 -0
- package/dist/storage_cache/suno_state.json +3 -0
- package/dist/suno_download.d.ts +11 -0
- package/dist/suno_download.d.ts.map +1 -0
- package/dist/suno_download.js +33 -0
- package/dist/suno_download.js.map +1 -0
- package/dist/suno_download.py +119 -0
- package/dist/test-web-element-requests.d.ts +6 -0
- package/dist/test-web-element-requests.d.ts.map +1 -0
- package/dist/test-web-element-requests.js +114 -0
- package/dist/test-web-element-requests.js.map +1 -0
- package/dist/test_pdf_render.d.ts +2 -0
- package/dist/test_pdf_render.d.ts.map +1 -0
- package/dist/test_pdf_render.js +50 -0
- package/dist/test_pdf_render.js.map +1 -0
- package/dist/training_data_viewer_endpoints.d.ts +2 -0
- package/dist/training_data_viewer_endpoints.d.ts.map +1 -0
- package/dist/training_data_viewer_endpoints.js +141 -0
- package/dist/training_data_viewer_endpoints.js.map +1 -0
- package/dist/utils.d.ts +353 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1517 -0
- package/dist/utils.js.map +1 -0
- package/dist/vm-h100.env.template +55 -0
- package/dist/web-element-requests.d.ts +102 -0
- package/dist/web-element-requests.d.ts.map +1 -0
- package/dist/web-element-requests.js +278 -0
- package/dist/web-element-requests.js.map +1 -0
- package/dist/workflowRoutes.d.ts +2 -0
- package/dist/workflowRoutes.d.ts.map +1 -0
- package/dist/workflowRoutes.js +441 -0
- package/dist/workflowRoutes.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
import { clearAllText, get, mouseClick, pasteText, pause, pressReturn } from '../../utils.js';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { fileModalOperate, isWindows, moveMouseDesktop, pressEscapeAsync, scroll } from '../../operations.js';
|
|
5
|
+
import robot from "robotjs";
|
|
6
|
+
import { captureScreenshot, captureScreenshotBase64 } from '../../inference/capturescreenshot.js';
|
|
7
|
+
import { classifyImageQuery, findImageInImageQuery, generalClassifyImageQuery } from '../runPrompt.js';
|
|
8
|
+
import { KEYS } from '../../constants.js';
|
|
9
|
+
import { similarityScore } from '../../operations/blender-ops.js';
|
|
10
|
+
import { SmartError } from '../error.js';
|
|
11
|
+
import { analyzeImageForTextAndIcons } from '../../promptRoutes.js';
|
|
12
|
+
import { ingestScreenshot } from '../self-learning/injest.js';
|
|
13
|
+
import { recordTransition } from '../self-learning/record_transition.js';
|
|
14
|
+
import { recognizeScreen } from '../self-learning/recognize.js';
|
|
15
|
+
/**
|
|
16
|
+
* Sets a value at a nested property path in an object
|
|
17
|
+
* @param {Object} obj - The object to set the value in
|
|
18
|
+
* @param {string} propertyPath - Dot-delimited path (e.g., "result.image")
|
|
19
|
+
* @param {*} value - The value to set
|
|
20
|
+
*/
|
|
21
|
+
function setNestedProperty(obj, propertyPath, value) {
|
|
22
|
+
if (!propertyPath)
|
|
23
|
+
return;
|
|
24
|
+
let keys = propertyPath.split('.');
|
|
25
|
+
let current = obj;
|
|
26
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
27
|
+
if (!current[keys[i]]) {
|
|
28
|
+
current[keys[i]] = {};
|
|
29
|
+
}
|
|
30
|
+
current = current[keys[i]];
|
|
31
|
+
}
|
|
32
|
+
current[keys[keys.length - 1]] = value;
|
|
33
|
+
console.log(`Stored value in output at ${propertyPath}`);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Gets a value from a nested property path in an object
|
|
37
|
+
* @param {Object} obj - The object to get the value from
|
|
38
|
+
* @param {string} propertyPath - Dot-delimited path (e.g., "result.image")
|
|
39
|
+
* @returns {*} The value at the nested property path, or undefined if not found
|
|
40
|
+
*/
|
|
41
|
+
function getNestedProperty(obj, propertyPath) {
|
|
42
|
+
if (!propertyPath || !obj)
|
|
43
|
+
return undefined;
|
|
44
|
+
let keys = propertyPath.split('.');
|
|
45
|
+
let current = obj;
|
|
46
|
+
for (let i = 0; i < keys.length; i++) {
|
|
47
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
current = current[keys[i]];
|
|
51
|
+
}
|
|
52
|
+
return current;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute key commands, handling both single commands and multiple commands
|
|
56
|
+
* @param {string} keys - The key command(s) to execute (e.g., "{up}", "{up}{up}{up}{up}", or plain text)
|
|
57
|
+
* @param {Object} inputs - Input data object
|
|
58
|
+
* @param {Object} params - Step parameters
|
|
59
|
+
*/
|
|
60
|
+
async function executeKeyCommands(keys, inputs, params) {
|
|
61
|
+
if (!keys)
|
|
62
|
+
return;
|
|
63
|
+
// Check if this contains multiple key commands (e.g., "{up}{up}{up}{up}")
|
|
64
|
+
const keyCommandRegex = /^\{[^}]+\}(\{[^}]+\})*$/;
|
|
65
|
+
if (keyCommandRegex.test(keys)) {
|
|
66
|
+
// Parse multiple key commands
|
|
67
|
+
const commandMatches = keys.match(/\{[^}]+\}/g);
|
|
68
|
+
if (commandMatches) {
|
|
69
|
+
console.log(`Executing ${commandMatches.length} key commands: ${keys}`);
|
|
70
|
+
for (const command of commandMatches) {
|
|
71
|
+
console.log(`Executing single key command: ${command}`);
|
|
72
|
+
await executeSingleKeyCommand(command);
|
|
73
|
+
// Small delay between key presses
|
|
74
|
+
await pause(() => { }, params.delay || 50);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Check if it's a single key command
|
|
80
|
+
const singleCommandRegex = /^\{[^}]+\}$/;
|
|
81
|
+
if (singleCommandRegex.test(keys)) {
|
|
82
|
+
console.log(`Executing single key command: ${keys}`);
|
|
83
|
+
await executeSingleKeyCommand(keys);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Not a key command, treat as text to type
|
|
87
|
+
let textToType = (inputs?.inputs || inputs.a)[params.textToType] || params.text || '';
|
|
88
|
+
console.log(`Typing text: ${textToType}`);
|
|
89
|
+
robot.typeString(textToType);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Execute a single key command
|
|
95
|
+
* @param {string} command - Single key command (e.g., "{up}", "{enter}")
|
|
96
|
+
*/
|
|
97
|
+
async function executeSingleKeyCommand(command) {
|
|
98
|
+
switch (command) {
|
|
99
|
+
case '{enter}':
|
|
100
|
+
pressReturn();
|
|
101
|
+
break;
|
|
102
|
+
case '{tab}':
|
|
103
|
+
robot.keyTap('tab');
|
|
104
|
+
break;
|
|
105
|
+
case '{right}':
|
|
106
|
+
robot.keyTap('right');
|
|
107
|
+
break;
|
|
108
|
+
case '{left}':
|
|
109
|
+
robot.keyTap('left');
|
|
110
|
+
break;
|
|
111
|
+
case '{up}':
|
|
112
|
+
robot.keyTap('up');
|
|
113
|
+
break;
|
|
114
|
+
case '{down}':
|
|
115
|
+
robot.keyTap('down');
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
console.log(`Unknown key command: ${command}`);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export async function executeConfiguration(workflowConfig, config, ctx, inputs, workflows) {
|
|
123
|
+
// Implementation for executing the workflow with the given config
|
|
124
|
+
const { workflow, jobs, subJobs } = workflowConfig;
|
|
125
|
+
const output = {};
|
|
126
|
+
console.log(`Executing workflow: ${workflow.id} with config:`, config);
|
|
127
|
+
const job = jobs?.find(job => job.id === config.version);
|
|
128
|
+
if (job) {
|
|
129
|
+
console.log(`Found job: ${job.id}`);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.warn(`Job not found for version: ${config.version}`);
|
|
133
|
+
// throw new Error(`Job not found for version: ${config.version}`);
|
|
134
|
+
}
|
|
135
|
+
// const subs = subJobs.filter(sub => sub.workflowId === workflow.id && sub.parentJobId === job.id);
|
|
136
|
+
let steps = workflow?.content?.steps || workflow?.steps;
|
|
137
|
+
let i = 0;
|
|
138
|
+
while (i < steps.length) {
|
|
139
|
+
const step = steps[i];
|
|
140
|
+
console.log(`Executing step: ${step.id}, step number ${i}`);
|
|
141
|
+
// Execute each step with the provided config
|
|
142
|
+
if (inputs?.inputs) {
|
|
143
|
+
let params = step?.params;
|
|
144
|
+
let tags = params?.selfLearningTags || [];
|
|
145
|
+
let hasTag = Object.keys(inputs?.inputs || {}).some(t => tags.includes(t));
|
|
146
|
+
if (!hasTag && !inputs?.inputs[params?.selfLearningMetadata?.name] &&
|
|
147
|
+
!inputs?.inputs[params?.selfLearningMetadata?.associated]) {
|
|
148
|
+
console.log(`No inputs found for step ${step.id}, skipping step.`);
|
|
149
|
+
console.log(`name: ${params?.selfLearningMetadata?.name}`);
|
|
150
|
+
console.log(`associated: ${params?.selfLearningMetadata?.associated}`);
|
|
151
|
+
i++;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
console.log(`name: ${params?.selfLearningMetadata?.name}`);
|
|
155
|
+
console.log(`associated: ${params?.selfLearningMetadata?.associated}`);
|
|
156
|
+
}
|
|
157
|
+
let res = await executeStep(workflow, job, step, ctx, inputs, output, workflows, config);
|
|
158
|
+
if (res.back) {
|
|
159
|
+
console.log(`Step requested going back, adjusting execution index.`);
|
|
160
|
+
i = Math.max(0, i - 1); // Go back 1 step, but don't go below 0
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
i++; // Only increment if not going back
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return output;
|
|
167
|
+
}
|
|
168
|
+
export async function executeStep(workflow, job, step, ctx, inputs, output, workflows, config, maxAttempts = 4) {
|
|
169
|
+
console.log(`------- inputs ---------`);
|
|
170
|
+
console.log(inputs);
|
|
171
|
+
// Implementation for executing a single step
|
|
172
|
+
/*
|
|
173
|
+
{
|
|
174
|
+
action: 'move_interact',
|
|
175
|
+
mediaType: 'image',
|
|
176
|
+
mediaUrl: 'https://firebasestorage.googleapis.com/v0/b/flowframe-auto.firebasestorage.app/o/users%2Fl7YvrqxTiogIlujkfp9oA6YMAvg2%2Fmedia%2F1754341845667_Screenshot_2025-08-04_at_4.10.26_PM.png?alt=media&token=25089088-56c3-4512-a405-c9e43bfdb7de',
|
|
177
|
+
timestampms: 2000,
|
|
178
|
+
type: 'move-interact',
|
|
179
|
+
id: 'c1fd8fe5-1f9e-42b9-a7e7-f2837015b655',
|
|
180
|
+
description: 'Move mouse and interact with elements',
|
|
181
|
+
params: {
|
|
182
|
+
targetX: 0.9226277372262773,
|
|
183
|
+
action: 'scroll',
|
|
184
|
+
generateAnnotations: true,
|
|
185
|
+
scrollAmount: 1000,
|
|
186
|
+
annotation: {
|
|
187
|
+
targetY: 1686,
|
|
188
|
+
imageHeight: 2658,
|
|
189
|
+
levels: [Array],
|
|
190
|
+
stepId: 'c1fd8fe5-1f9e-42b9-a7e7-f2837015b655',
|
|
191
|
+
targetX: 3794,
|
|
192
|
+
imageWidth: 4112
|
|
193
|
+
},
|
|
194
|
+
targetY: 0.6343778671748183,
|
|
195
|
+
singleLevel: true,
|
|
196
|
+
noLevel: false,
|
|
197
|
+
className: 'target',
|
|
198
|
+
levelReduction: 0.25,
|
|
199
|
+
minPixelSize: 20,
|
|
200
|
+
rootPercentage: 0.25,
|
|
201
|
+
actualMediaSize: { height: 2658, width: 4112 }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
*/
|
|
205
|
+
console.log(`Executing step action: ${step.action} with params:`, step.params);
|
|
206
|
+
if (step?.params?.smart) {
|
|
207
|
+
// Smart parameter handling can be implemented here
|
|
208
|
+
/* "smart": {
|
|
209
|
+
"cropHeight": 50,
|
|
210
|
+
"text": "lie, electronic",
|
|
211
|
+
"hasText": true,
|
|
212
|
+
"cropWidth": 140,
|
|
213
|
+
"hasIcon": false,
|
|
214
|
+
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUh"
|
|
215
|
+
}*/
|
|
216
|
+
let grade = 0;
|
|
217
|
+
let maxAttempts = 5;
|
|
218
|
+
try {
|
|
219
|
+
do {
|
|
220
|
+
grade = await evaluateSmartly(inputs, step);
|
|
221
|
+
console.log(`Grade for smart analysis: ${grade}`);
|
|
222
|
+
if (!grade)
|
|
223
|
+
await pause(() => { }, 1000);
|
|
224
|
+
} while (grade < 1 && maxAttempts-- > 0);
|
|
225
|
+
if (grade > 0) {
|
|
226
|
+
console.log(`Smart analysis passed with grade: ${grade}, proceeding with step action.`);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
console.log(`Smart analysis failed after multiple attempts, skipping step action.`);
|
|
230
|
+
let message = '';
|
|
231
|
+
if (step.params.smart.hasText) {
|
|
232
|
+
message += `Expected text: ${step.params.smart.text}`;
|
|
233
|
+
}
|
|
234
|
+
if (step.params.smart.hasIcon) {
|
|
235
|
+
message += `Expected icon presence: ${step.params.smart.hasIcon}`;
|
|
236
|
+
}
|
|
237
|
+
if (!step.params.validateWithSmartSkippable) {
|
|
238
|
+
throw new SmartError(`Smart analysis failed for step ${step.id}`, { details: message });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
console.log(`Error during smart analysis: ${e}, skipping step action.`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (true) {
|
|
247
|
+
await performAction();
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
await recordTransition({
|
|
251
|
+
takeScreenshot: async () => {
|
|
252
|
+
let filename = `step_${step.id}_before_${Date.now()}.png`;
|
|
253
|
+
await captureScreenshot(get(KEYS.screen_shot_folder), filename);
|
|
254
|
+
return path.join(get(KEYS.screen_shot_folder), filename);
|
|
255
|
+
},
|
|
256
|
+
recognizeScreen: async (imagePath) => {
|
|
257
|
+
return recognizeScreen(imagePath);
|
|
258
|
+
},
|
|
259
|
+
performAction,
|
|
260
|
+
action: step.action,
|
|
261
|
+
meta: { stepId: step.id }
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async function performAction() {
|
|
265
|
+
const SCREEN = robot.getScreenSize();
|
|
266
|
+
switch (step.action) {
|
|
267
|
+
case 'pause':
|
|
268
|
+
console.log('Waiting for', step.params.duration || 1000, 'ms');
|
|
269
|
+
await pause(() => { }, step.params.duration || 1000);
|
|
270
|
+
console.log(`Completed wait of ${step.params.duration || 1000} ms`);
|
|
271
|
+
break;
|
|
272
|
+
case 'type':
|
|
273
|
+
{
|
|
274
|
+
console.log(`Typing input for step ${step.id}`);
|
|
275
|
+
console.log(`Step params:`, step.params);
|
|
276
|
+
console.log(`step.params.keys: ${step.params.keys}`);
|
|
277
|
+
await pause(() => { }, 1000);
|
|
278
|
+
await executeKeyCommands(step.params.keys, inputs, step.params);
|
|
279
|
+
await pause(() => { }, 1000);
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
case 'combination_move-interact':
|
|
283
|
+
{
|
|
284
|
+
console.log(`Executing combination move interact for step ${step.id}`);
|
|
285
|
+
let count = getNestedProperty(inputs?.inputs || inputs.a, step.params.countProperty);
|
|
286
|
+
console.log(`Retrieved count from inputs at ${step.params.countProperty}: ${count}`);
|
|
287
|
+
if (count)
|
|
288
|
+
count = parseInt(count);
|
|
289
|
+
console.log(`count for combination steps: ${count}`);
|
|
290
|
+
for (let i = 0; i < (count || step.params.count || 1); i++) {
|
|
291
|
+
for (const [idx, subStep] of (step.params.steps || []).entries()) {
|
|
292
|
+
console.log(` Executing sub-step ${idx + 1}:`, subStep);
|
|
293
|
+
await executeStep(workflow, job, subStep, ctx, inputs, output, workflows, config, maxAttempts);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
case 'automation':
|
|
299
|
+
{
|
|
300
|
+
let automationName = step.params.automationName;
|
|
301
|
+
if (automationName.endsWith('.automation')) {
|
|
302
|
+
automationName = automationName.slice(0, -'.automation'.length);
|
|
303
|
+
}
|
|
304
|
+
const workflow = workflows.find(wf => {
|
|
305
|
+
console.log(wf);
|
|
306
|
+
return wf.workflow.id === automationName;
|
|
307
|
+
});
|
|
308
|
+
if (!workflow) {
|
|
309
|
+
console.log(`There are ${workflows.length} workflows loaded:`);
|
|
310
|
+
console.log(workflows.map(d => `${d.workflow.id}=> ${d.workflow.name}`).join('\n'));
|
|
311
|
+
throw new Error(`Workflow not found: ${automationName}`);
|
|
312
|
+
}
|
|
313
|
+
await executeConfiguration(workflow, config, ctx, inputs, workflows);
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
case 'move_interact':
|
|
317
|
+
{
|
|
318
|
+
if (step?.params?.selfLearningTags?.length) {
|
|
319
|
+
let targetFolder = get(KEYS.screen_shot_folder);
|
|
320
|
+
if (fs.existsSync(targetFolder)) {
|
|
321
|
+
let filename = await captureScreenshot(get(KEYS.screen_shot_folder), `automation_step_${step.id}_${Date.now()}.png`);
|
|
322
|
+
let filePath = path.join(targetFolder, filename);
|
|
323
|
+
await ingestScreenshot({
|
|
324
|
+
imagePath: filePath,
|
|
325
|
+
meta: step?.params?.selfLearningMetadata || {},
|
|
326
|
+
tags: step?.params?.selfLearningTags || []
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
throw new Error(`Screen shot folder does not exist: ${targetFolder}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const SCREEN = robot.getScreenSize();
|
|
334
|
+
if (step.params.targetProperty) {
|
|
335
|
+
// read from inputs
|
|
336
|
+
let target = getNestedProperty(inputs, step.params.targetProperty);
|
|
337
|
+
if (target) {
|
|
338
|
+
step.params.targetX = target.x;
|
|
339
|
+
step.params.targetY = target.y;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
throw new Error(`Target property ${step.params.targetProperty} not found in inputs`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
let center = {
|
|
346
|
+
left: step.params.targetX * SCREEN.width,
|
|
347
|
+
top: step.params.targetY * SCREEN.height,
|
|
348
|
+
height: 2,
|
|
349
|
+
width: 2
|
|
350
|
+
};
|
|
351
|
+
await moveMouseDesktop(center);
|
|
352
|
+
await pause(() => { }, 1000);
|
|
353
|
+
console.log(`********* Performing action: ${step.params.action} *********`);
|
|
354
|
+
switch (step.params.action) {
|
|
355
|
+
case "click":
|
|
356
|
+
await mouseClick();
|
|
357
|
+
break;
|
|
358
|
+
case "double_click":
|
|
359
|
+
await mouseClick();
|
|
360
|
+
await pause(() => { }, 100);
|
|
361
|
+
await mouseClick();
|
|
362
|
+
break;
|
|
363
|
+
case 'selectAllAndClear':
|
|
364
|
+
{
|
|
365
|
+
clearAllText();
|
|
366
|
+
}
|
|
367
|
+
break;
|
|
368
|
+
case "file_modal_selection":
|
|
369
|
+
{
|
|
370
|
+
// Implementation for file modal selection can go here
|
|
371
|
+
let text = (inputs?.inputs || inputs.a)[step.params.filePropertyName];
|
|
372
|
+
if (!text) {
|
|
373
|
+
console.warn(`No text found in inputs?.inputs or inputs.a for property name: ${step.params.filePropertyName}`);
|
|
374
|
+
throw new Error(`No text found in inputs?.inputs or inputs.a for property name: ${step.params.filePropertyName}`);
|
|
375
|
+
}
|
|
376
|
+
if (!fs.existsSync(text)) {
|
|
377
|
+
console.log(`File does not exist at path: ${text}`);
|
|
378
|
+
throw new Error(`File does not exist at path: ${text}`);
|
|
379
|
+
}
|
|
380
|
+
await fileModalOperate(text);
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case 'go_back_if':
|
|
384
|
+
{
|
|
385
|
+
const SCREEN = robot.getScreenSize();
|
|
386
|
+
let answer = 'no'; // Declare outside the loop
|
|
387
|
+
await pause(() => { }, 5 * 1000);
|
|
388
|
+
// Capture the specified area
|
|
389
|
+
let area = {
|
|
390
|
+
x: step.params.left * SCREEN.width,
|
|
391
|
+
y: step.params.top * SCREEN.height,
|
|
392
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
393
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
394
|
+
};
|
|
395
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
396
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
397
|
+
let prompt = step.params.prompt || "Is the condition met in the image?";
|
|
398
|
+
console.log(`Asking question: ${prompt}`);
|
|
399
|
+
let model = step.params.llm || 'gpt-4';
|
|
400
|
+
let result = await classifyImageQuery(model, prompt, base64Image);
|
|
401
|
+
answer = result.answer; // Update the outer scope variable
|
|
402
|
+
let { confidence, reason } = result;
|
|
403
|
+
console.log(`Answer: ${answer}, Confidence: ${confidence}, Reason: ${reason}`);
|
|
404
|
+
console.log(`answer(${answer}) !== 'yes': ${answer !== 'yes'}`);
|
|
405
|
+
if (answer === 'yes') {
|
|
406
|
+
console.log(`Condition met, going back.`);
|
|
407
|
+
return { back: true };
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
case 'wait_on_area':
|
|
412
|
+
{
|
|
413
|
+
const SCREEN = robot.getScreenSize();
|
|
414
|
+
let answer = 'no'; // Declare outside the loop
|
|
415
|
+
const maxWaitTime = (parseInt(`${step.params.maxWaitTime}`) || 60) * 1000 * 60; // default 60 minutes
|
|
416
|
+
const interval = parseInt(`${step.params.interval}`) || 5000; // default 5 seconds
|
|
417
|
+
const startTime = Date.now();
|
|
418
|
+
do {
|
|
419
|
+
// Capture the specified area
|
|
420
|
+
let area = {
|
|
421
|
+
x: step.params.left * SCREEN.width,
|
|
422
|
+
y: step.params.top * SCREEN.height,
|
|
423
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
424
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
425
|
+
};
|
|
426
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
427
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
428
|
+
let prompt = step.params.prompt || "Is the condition met in the image?";
|
|
429
|
+
console.log(`Asking question: ${prompt}`);
|
|
430
|
+
let model = step.params.llm || 'gpt-4';
|
|
431
|
+
let result = await classifyImageQuery(model, prompt, base64Image);
|
|
432
|
+
answer = result.answer; // Update the outer scope variable
|
|
433
|
+
let { confidence, reason } = result;
|
|
434
|
+
console.log(`Answer: ${answer}, Confidence: ${confidence}, Reason: ${reason}`);
|
|
435
|
+
console.log(`answer(${answer}) !== 'yes': ${answer !== 'yes'}`);
|
|
436
|
+
if (answer !== 'yes') {
|
|
437
|
+
await pause(() => { }, interval);
|
|
438
|
+
}
|
|
439
|
+
} while (Date.now() - startTime < maxWaitTime && answer !== 'yes');
|
|
440
|
+
if (answer === 'no') {
|
|
441
|
+
console.error(`Condition not met within max wait time of ${maxWaitTime} ms`);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
break;
|
|
445
|
+
case 'query_image_question':
|
|
446
|
+
{
|
|
447
|
+
// Capture the specified area
|
|
448
|
+
let area = {
|
|
449
|
+
x: step.params.left * SCREEN.width,
|
|
450
|
+
y: step.params.top * SCREEN.height,
|
|
451
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
452
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
453
|
+
};
|
|
454
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
455
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
456
|
+
let prompt = step.params.prompt || "Is the condition met in the image?";
|
|
457
|
+
console.log(`Asking question: ${prompt}`);
|
|
458
|
+
let model = step.params.llm || 'gpt-4';
|
|
459
|
+
let result = await generalClassifyImageQuery(model, prompt, base64Image);
|
|
460
|
+
console.log(`Answer: ${result}`);
|
|
461
|
+
const outputProperty = step.params.property;
|
|
462
|
+
if (outputProperty) {
|
|
463
|
+
setNestedProperty(output, outputProperty, result);
|
|
464
|
+
}
|
|
465
|
+
const areaProperty = step.params.areaProperty;
|
|
466
|
+
if (areaProperty) {
|
|
467
|
+
setNestedProperty(output, areaProperty, area);
|
|
468
|
+
}
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
case 'find_image_in_image':
|
|
472
|
+
{
|
|
473
|
+
// Capture the specified area
|
|
474
|
+
let area = {
|
|
475
|
+
x: step.params.left * SCREEN.width,
|
|
476
|
+
y: step.params.top * SCREEN.height,
|
|
477
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
478
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
479
|
+
};
|
|
480
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
481
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
482
|
+
let templateImageBase64 = step.params.targetImageBase64;
|
|
483
|
+
// Add data URL prefix if not present
|
|
484
|
+
if (templateImageBase64 && !templateImageBase64.startsWith('data:')) {
|
|
485
|
+
templateImageBase64 = `data:image/png;base64,${templateImageBase64}`;
|
|
486
|
+
}
|
|
487
|
+
console.log(`Finding template image in captured area.`);
|
|
488
|
+
let result = await findImageInImageQuery(step.params.llm || 'gpt-4', templateImageBase64, base64Image);
|
|
489
|
+
console.log(`Result: ${JSON.stringify(result)}`);
|
|
490
|
+
// Calculate center coordinates relative to SCREEN if box is found
|
|
491
|
+
if (result && result.box && result.box.x_center_rel !== undefined && result.box.y_center_rel !== undefined) {
|
|
492
|
+
// The box coordinates are relative to the captured area, so convert to screen-relative coordinates (0-1)
|
|
493
|
+
const absoluteCenterX = area.x + (result.box.x_center_rel * area.width);
|
|
494
|
+
const absoluteCenterY = area.y + (result.box.y_center_rel * area.height);
|
|
495
|
+
const centerX = absoluteCenterX / SCREEN.width;
|
|
496
|
+
const centerY = absoluteCenterY / SCREEN.height;
|
|
497
|
+
result.center = {
|
|
498
|
+
x: centerX,
|
|
499
|
+
y: centerY,
|
|
500
|
+
targetX: centerX,
|
|
501
|
+
targetY: centerY
|
|
502
|
+
};
|
|
503
|
+
console.log(`Calculated center coordinates relative to screen: (${centerX}, ${centerY})`);
|
|
504
|
+
}
|
|
505
|
+
const outputProperty = step.params.property;
|
|
506
|
+
if (outputProperty) {
|
|
507
|
+
setNestedProperty(output, outputProperty, result);
|
|
508
|
+
setNestedProperty(inputs, outputProperty, result);
|
|
509
|
+
}
|
|
510
|
+
const areaProperty = step.params.areaProperty;
|
|
511
|
+
if (areaProperty) {
|
|
512
|
+
setNestedProperty(output, areaProperty, area);
|
|
513
|
+
}
|
|
514
|
+
let t = {
|
|
515
|
+
"blenderImage": {
|
|
516
|
+
"found": true,
|
|
517
|
+
"confidence": 0.9,
|
|
518
|
+
"box": {
|
|
519
|
+
"x_center_rel": 0.934,
|
|
520
|
+
"y_center_rel": 0.83,
|
|
521
|
+
"width_rel": 0.03,
|
|
522
|
+
"height_rel": 0.15
|
|
523
|
+
},
|
|
524
|
+
"reason": "The Blender icon in the dock matches the query image.",
|
|
525
|
+
"center": {
|
|
526
|
+
"x": 0.9260384615384615,
|
|
527
|
+
"y": 0.9750666666666667
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
"blenderArea": {
|
|
531
|
+
"x": 20.56,
|
|
532
|
+
"y": 1134.0800000000002,
|
|
533
|
+
"width": 2016.4615384615383,
|
|
534
|
+
"height": 194.91999999999993
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
case 'query_yes_or_no_on_area':
|
|
540
|
+
{
|
|
541
|
+
let answer = 'no'; // Declare outside the loop
|
|
542
|
+
// Capture the specified area
|
|
543
|
+
let area = {
|
|
544
|
+
x: step.params.left * SCREEN.width,
|
|
545
|
+
y: step.params.top * SCREEN.height,
|
|
546
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
547
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
548
|
+
};
|
|
549
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
550
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
551
|
+
let prompt = step.params.prompt || "Is the condition met in the image?";
|
|
552
|
+
console.log(`Asking question: ${prompt}`);
|
|
553
|
+
let model = step.params.llm || 'gpt-4';
|
|
554
|
+
let result = await classifyImageQuery(model, prompt, base64Image);
|
|
555
|
+
answer = result.answer; // Update the outer scope variable
|
|
556
|
+
let { confidence, reason } = result;
|
|
557
|
+
console.log(`Answer: ${answer}, Confidence: ${confidence}, Reason: ${reason}`);
|
|
558
|
+
console.log(`answer(${answer}) !== 'yes': ${answer !== 'yes'}`);
|
|
559
|
+
const outputProperty = step.params.property;
|
|
560
|
+
if (outputProperty) {
|
|
561
|
+
setNestedProperty(output, outputProperty, answer);
|
|
562
|
+
}
|
|
563
|
+
const areaProperty = step.params.areaProperty;
|
|
564
|
+
if (areaProperty) {
|
|
565
|
+
setNestedProperty(output, areaProperty, area);
|
|
566
|
+
}
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
case 'capture_area':
|
|
570
|
+
{
|
|
571
|
+
// Capture the specified area
|
|
572
|
+
let area = {
|
|
573
|
+
x: step.params.left * SCREEN.width,
|
|
574
|
+
y: step.params.top * SCREEN.height,
|
|
575
|
+
width: (step.params.right - step.params.left) * SCREEN.width,
|
|
576
|
+
height: (step.params.bottom - step.params.top) * SCREEN.height
|
|
577
|
+
};
|
|
578
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
579
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
580
|
+
// Also store in output if property is specified
|
|
581
|
+
const outputProperty = step.params.property;
|
|
582
|
+
if (outputProperty) {
|
|
583
|
+
setNestedProperty(output, outputProperty, base64Image);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
console.log(`Captured area and stored in inputs.a[${step.id}]`);
|
|
587
|
+
}
|
|
588
|
+
const areaProperty = step.params.areaProperty;
|
|
589
|
+
if (areaProperty) {
|
|
590
|
+
setNestedProperty(output, areaProperty, area);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
break;
|
|
594
|
+
case "paste":
|
|
595
|
+
{
|
|
596
|
+
// Paste from clipboard
|
|
597
|
+
let text = (inputs?.inputs || inputs.a)[step.params.textToType];
|
|
598
|
+
console.log(`Pasting text: ${text}`);
|
|
599
|
+
await pasteText(text);
|
|
600
|
+
console.log(`Pasted text successfully.`);
|
|
601
|
+
}
|
|
602
|
+
break;
|
|
603
|
+
case "scroll":
|
|
604
|
+
await scroll(0, step.params.scrollAmount || 1000);
|
|
605
|
+
break;
|
|
606
|
+
case 'type':
|
|
607
|
+
{
|
|
608
|
+
// await text(step.params.text || '');
|
|
609
|
+
let text = (inputs?.inputs || inputs.a)[step.params.textToType] || step.params.text;
|
|
610
|
+
console.log(`Typing text: ${text}`);
|
|
611
|
+
robot.typeString(text || '');
|
|
612
|
+
}
|
|
613
|
+
break;
|
|
614
|
+
case 'pressEscape':
|
|
615
|
+
await mouseClick();
|
|
616
|
+
await pressEscapeAsync();
|
|
617
|
+
break;
|
|
618
|
+
case 'pressAndDrag':
|
|
619
|
+
let dragTo = {
|
|
620
|
+
left: (step.params.targetX * SCREEN.width) + (((step.params.dragToX) || 0) * SCREEN.width),
|
|
621
|
+
top: (step.params.targetY * SCREEN.height) + (((step.params.dragToY) || 0) * SCREEN.height),
|
|
622
|
+
height: 2,
|
|
623
|
+
width: 2
|
|
624
|
+
};
|
|
625
|
+
robot.mouseToggle("down");
|
|
626
|
+
await pause(() => { }, 500);
|
|
627
|
+
await moveMouseDesktop(dragTo, 2000);
|
|
628
|
+
await pause(() => { }, 500);
|
|
629
|
+
robot.mouseToggle("up");
|
|
630
|
+
break;
|
|
631
|
+
case 'clickAndCopyText':
|
|
632
|
+
await mouseClick();
|
|
633
|
+
// Select all agnosticly for all OSs
|
|
634
|
+
robot.keyToggle('a', 'down', process.platform === "darwin" ? "command" : "control");
|
|
635
|
+
await pause(() => { }, 500);
|
|
636
|
+
robot.keyToggle('a', 'up', process.platform === "darwin" ? "command" : "control");
|
|
637
|
+
// Copy to clipboard
|
|
638
|
+
robot.keyToggle('c', 'down', process.platform === "darwin" ? "command" : "control");
|
|
639
|
+
await pause(() => { }, 500);
|
|
640
|
+
robot.keyToggle('c', 'up', process.platform === "darwin" ? "command" : "control");
|
|
641
|
+
await pause(() => { }, 500);
|
|
642
|
+
let clipboard = (await import('clipboardy')).default;
|
|
643
|
+
;
|
|
644
|
+
let copiedText = clipboard.readSync();
|
|
645
|
+
// Store copied text in inputs for later steps
|
|
646
|
+
let outputString = step.params.output || '';
|
|
647
|
+
//outputString can be dot delimited keys like "result.text"
|
|
648
|
+
setNestedProperty(output, outputString, copiedText);
|
|
649
|
+
console.log(`Copied text: ${copiedText}`);
|
|
650
|
+
break;
|
|
651
|
+
default:
|
|
652
|
+
console.log(`Unknown action: ${step.params.action}`);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
break;
|
|
656
|
+
case 'switch':
|
|
657
|
+
{
|
|
658
|
+
console.log(`Executing switch step ${step.id}`);
|
|
659
|
+
const { cases, defaultCase, switchProperty } = step.params;
|
|
660
|
+
// Get the condition value from the condition input
|
|
661
|
+
const switchValue = inputs?.a?.[switchProperty];
|
|
662
|
+
console.log(`Switch condition value:`, switchValue);
|
|
663
|
+
// Find the matching case
|
|
664
|
+
let caseStep = null;
|
|
665
|
+
if (switchValue !== undefined && cases && cases[switchValue]) {
|
|
666
|
+
caseStep = cases[switchValue];
|
|
667
|
+
console.log(`Found matching case "${switchValue}" for step ${step.id}`);
|
|
668
|
+
}
|
|
669
|
+
else if (defaultCase) {
|
|
670
|
+
caseStep = defaultCase;
|
|
671
|
+
console.log(`No matching case found, using default case for step ${step.id}`);
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
console.log(`No matching case and no default case for step ${step.id}, skipping`);
|
|
675
|
+
}
|
|
676
|
+
// Execute the case step if found
|
|
677
|
+
if (caseStep) {
|
|
678
|
+
console.log(`Executing case step:`, caseStep);
|
|
679
|
+
await executeStep(workflow, job, caseStep, ctx, inputs, output, workflows, config, maxAttempts);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
await pause(() => { }, 500);
|
|
686
|
+
return {};
|
|
687
|
+
}
|
|
688
|
+
async function evaluateSmartly(inputs, step) {
|
|
689
|
+
const SCREEN = robot.getScreenSize();
|
|
690
|
+
if (step.params.targetProperty) {
|
|
691
|
+
// read from inputs
|
|
692
|
+
let target = getNestedProperty(inputs, step.params.targetProperty);
|
|
693
|
+
if (target) {
|
|
694
|
+
step.params.targetX = target.x;
|
|
695
|
+
step.params.targetY = target.y;
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
throw new Error(`Target property ${step.params.targetProperty} not found in inputs`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
console.log(`Smart parameters detected for step ${step.id}:`, step.params.smart);
|
|
702
|
+
let model = get(KEYS.default_llm_model);
|
|
703
|
+
let multiModalModel = get(KEYS.default_llm_multi_modal_model);
|
|
704
|
+
console.log(`Using default LLM model: ${model} and multi-modal model: ${multiModalModel}`);
|
|
705
|
+
let area = {
|
|
706
|
+
x: step.params.targetX * SCREEN.width - (step.params.smart.cropWidth / 2),
|
|
707
|
+
y: step.params.targetY * SCREEN.height - (step.params.smart.cropHeight / 2),
|
|
708
|
+
width: step.params.smart.cropWidth,
|
|
709
|
+
height: step.params.smart.cropHeight
|
|
710
|
+
};
|
|
711
|
+
console.log(`Capturing area: ${JSON.stringify(area)}`);
|
|
712
|
+
const base64Image = await captureScreenshotBase64(area);
|
|
713
|
+
// Compare expected vs actual, and grade.
|
|
714
|
+
let grade = 0;
|
|
715
|
+
if (!step.params.validateWithSmart && !step?.params?.validateWithSmartText) {
|
|
716
|
+
grade = 1;
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
let { parsed } = await analyzeImageForTextAndIcons(base64Image, multiModalModel);
|
|
720
|
+
console.log(`Parsed smart analysis result:`, parsed);
|
|
721
|
+
if (step.params.smart.hasText) {
|
|
722
|
+
if (parsed.hasText) {
|
|
723
|
+
let lDistance = similarityScore(`${parsed.text}`, `${step.params.smart.text}`);
|
|
724
|
+
if (lDistance >= (step?.params?.validateWithSmartText * 100)) {
|
|
725
|
+
grade += 1;
|
|
726
|
+
}
|
|
727
|
+
console.log(`Text similarity score: ${lDistance}, grade: ${grade}`);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (step.params.smart.hasIcon) {
|
|
731
|
+
if (parsed.hasIcon) {
|
|
732
|
+
grade += 0.5;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return grade;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Convert a detection result to { left, top, width, height }.
|
|
740
|
+
* @param {Object} result - Object with a `bbox` field.
|
|
741
|
+
* @param {Object} [opts]
|
|
742
|
+
* @param {boolean} [opts.useLocal=true] - Prefer local_x1/local_y1 when available.
|
|
743
|
+
* @param {boolean} [opts.round=false] - Round numbers to `precision` decimals.
|
|
744
|
+
* @param {number} [opts.precision=2]
|
|
745
|
+
*/
|
|
746
|
+
function toLTWH(result, { useLocal = true, round = false, precision = 2 } = {}) {
|
|
747
|
+
if (!result || !result.bbox)
|
|
748
|
+
throw new Error('Invalid result: missing bbox');
|
|
749
|
+
const b = result.bbox;
|
|
750
|
+
const left = (useLocal && 'local_x1' in b) ? b.local_x1 : b.x1;
|
|
751
|
+
const top = (useLocal && 'local_y1' in b) ? b.local_y1 : b.y1;
|
|
752
|
+
const width = ('width' in b) ? b.width : (b.x2 - b.x1);
|
|
753
|
+
const height = ('height' in b) ? b.height : (b.y2 - b.y1);
|
|
754
|
+
const rect = { left, top, width, height };
|
|
755
|
+
let factor = 2;
|
|
756
|
+
if (isWindows()) {
|
|
757
|
+
factor = 1;
|
|
758
|
+
}
|
|
759
|
+
if (round) {
|
|
760
|
+
const f = n => Number(n.toFixed(precision));
|
|
761
|
+
rect.left = f(rect.left / factor);
|
|
762
|
+
rect.top = f(rect.top / factor);
|
|
763
|
+
rect.width = f(rect.width / factor);
|
|
764
|
+
rect.height = f(rect.height / factor);
|
|
765
|
+
}
|
|
766
|
+
return rect;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Get the center point of a detection result.
|
|
770
|
+
* @param {{ bbox: { x1?:number, y1?:number, x2?:number, y2?:number, width?:number, height?:number, local_x1?:number, local_y1?:number, local_x2?:number, local_y2?:number } }} result
|
|
771
|
+
* @param {"global"|"local"} [space="global"] Use "local" to prefer local_* coords if present.
|
|
772
|
+
* @returns {{ x:number, y:number }}
|
|
773
|
+
*/
|
|
774
|
+
function getCenter(result, space = "global") {
|
|
775
|
+
const b = (result && result.bbox) || {};
|
|
776
|
+
const F = Number.isFinite;
|
|
777
|
+
if (space === "local") {
|
|
778
|
+
if (F(b.local_x1) && F(b.local_x2) && F(b.local_y1) && F(b.local_y2)) {
|
|
779
|
+
return { x: (b.local_x1 + b.local_x2) / 2, y: (b.local_y1 + b.local_y2) / 2 };
|
|
780
|
+
}
|
|
781
|
+
if (F(b.local_x1) && F(b.local_y1) && F(b.width) && F(b.height)) {
|
|
782
|
+
return { x: b.local_x1 + b.width / 2, y: b.local_y1 + b.height / 2 };
|
|
783
|
+
}
|
|
784
|
+
throw new Error("Local coordinates not available on bbox.");
|
|
785
|
+
}
|
|
786
|
+
// global (default)
|
|
787
|
+
if (F(b.x1) && F(b.x2) && F(b.y1) && F(b.y2)) {
|
|
788
|
+
return { x: (b.x1 + b.x2) / 2, y: (b.y1 + b.y2) / 2 };
|
|
789
|
+
}
|
|
790
|
+
if (F(b.x1) && F(b.y1) && F(b.width) && F(b.height)) {
|
|
791
|
+
return { x: b.x1 + b.width / 2, y: b.y1 + b.height / 2 };
|
|
792
|
+
}
|
|
793
|
+
throw new Error("Global coordinates not available on bbox.");
|
|
794
|
+
}
|
|
795
|
+
//# sourceMappingURL=executor.js.map
|