android-midscene-automation 0.2.3 → 1.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/CHANGELOG.md +11 -1
- package/README.md +63 -1
- package/artemis-main/.dockerignore +15 -0
- package/artemis-main/.env.example +34 -0
- package/artemis-main/CONTRIBUTING.md +35 -0
- package/artemis-main/Dockerfile +68 -0
- package/artemis-main/LICENSE +202 -0
- package/artemis-main/Makefile +115 -0
- package/artemis-main/README.md +322 -0
- package/artemis-main/README_CN.md +320 -0
- package/artemis-main/apps/__init__.py +15 -0
- package/artemis-main/apps/admin_console/__init__.py +19 -0
- package/artemis-main/apps/admin_console/core/__init__.py +13 -0
- package/artemis-main/apps/admin_console/core/config.py +43 -0
- package/artemis-main/apps/admin_console/core/security.py +178 -0
- package/artemis-main/apps/admin_console/core/state.py +243 -0
- package/artemis-main/apps/admin_console/database/__init__.py +13 -0
- package/artemis-main/apps/admin_console/database/connection.py +60 -0
- package/artemis-main/apps/admin_console/database/repositories/__init__.py +13 -0
- package/artemis-main/apps/admin_console/database/repositories/session_repository.py +564 -0
- package/artemis-main/apps/admin_console/database/repositories/step_repository.py +512 -0
- package/artemis-main/apps/admin_console/database/repositories/trace_repository.py +133 -0
- package/artemis-main/apps/admin_console/index.html +3787 -0
- package/artemis-main/apps/admin_console/replay_manager.py +2585 -0
- package/artemis-main/apps/admin_console/routers/__init__.py +13 -0
- package/artemis-main/apps/admin_console/routers/media.py +198 -0
- package/artemis-main/apps/admin_console/routers/replay.py +91 -0
- package/artemis-main/apps/admin_console/routers/sessions.py +239 -0
- package/artemis-main/apps/admin_console/routers/steps.py +109 -0
- package/artemis-main/apps/admin_console/routers/stream.py +56 -0
- package/artemis-main/apps/admin_console/routers/system.py +761 -0
- package/artemis-main/apps/admin_console/routers/tasks.py +517 -0
- package/artemis-main/apps/admin_console/schemas/__init__.py +13 -0
- package/artemis-main/apps/admin_console/schemas/task_schema.py +47 -0
- package/artemis-main/apps/admin_console/server.py +508 -0
- package/artemis-main/apps/admin_console/services/__init__.py +13 -0
- package/artemis-main/apps/admin_console/services/device_stream_service.py +137 -0
- package/artemis-main/apps/admin_console/services/ipc_service.py +262 -0
- package/artemis-main/apps/admin_console/services/media_service.py +623 -0
- package/artemis-main/apps/admin_console/services/model_service.py +148 -0
- package/artemis-main/apps/admin_console/services/task_preset_catalog.py +514 -0
- package/artemis-main/apps/admin_console/services/task_queue_service.py +1719 -0
- package/artemis-main/apps/admin_console/services/worker_process_io.py +144 -0
- package/artemis-main/apps/showcase_ui/README.md +31 -0
- package/artemis-main/apps/showcase_ui/angular.json +132 -0
- package/artemis-main/apps/showcase_ui/package-lock.json +9472 -0
- package/artemis-main/apps/showcase_ui/package.json +39 -0
- package/artemis-main/apps/showcase_ui/proxy.conf.json +23 -0
- package/artemis-main/apps/showcase_ui/public/favicon.ico +0 -0
- package/artemis-main/apps/showcase_ui/public/logo.png +0 -0
- package/artemis-main/apps/showcase_ui/public/logo.svg +56 -0
- package/artemis-main/apps/showcase_ui/src/app/app.component.html +24 -0
- package/artemis-main/apps/showcase_ui/src/app/app.component.scss +49 -0
- package/artemis-main/apps/showcase_ui/src/app/app.component.spec.ts +42 -0
- package/artemis-main/apps/showcase_ui/src/app/app.component.ts +32 -0
- package/artemis-main/apps/showcase_ui/src/app/app.config.ts +29 -0
- package/artemis-main/apps/showcase_ui/src/app/app.routes.ts +27 -0
- package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream-startup.spec.ts +108 -0
- package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.html +1436 -0
- package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.scss +3973 -0
- package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.ts +2235 -0
- package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.html +380 -0
- package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.scss +1171 -0
- package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.ts +270 -0
- package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.html +433 -0
- package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.scss +987 -0
- package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.ts +632 -0
- package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.html +130 -0
- package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.scss +406 -0
- package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.ts +74 -0
- package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.scss +115 -0
- package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.ts +52 -0
- package/artemis-main/apps/showcase_ui/src/app/core/data/smart-tasks.data.ts +334 -0
- package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.spec.ts +55 -0
- package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.ts +61 -0
- package/artemis-main/apps/showcase_ui/src/app/core/i18n/translate.pipe.ts +11 -0
- package/artemis-main/apps/showcase_ui/src/app/core/i18n/zh-cn.ts +651 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/markdown.model.ts +43 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.spec.ts +47 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.ts +165 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/session.model.ts +85 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/stream.model.ts +246 -0
- package/artemis-main/apps/showcase_ui/src/app/core/models/system.model.ts +118 -0
- package/artemis-main/apps/showcase_ui/src/app/core/services/task-recommendation.service.ts +111 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.html +2130 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.scss +5204 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.ts +1189 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.html +39 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.scss +151 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.ts +58 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.html +201 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.scss +886 -0
- package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.ts +324 -0
- package/artemis-main/apps/showcase_ui/src/app/services/agent.service.spec.ts +418 -0
- package/artemis-main/apps/showcase_ui/src/app/services/agent.service.ts +2012 -0
- package/artemis-main/apps/showcase_ui/src/app/services/system.service.spec.ts +173 -0
- package/artemis-main/apps/showcase_ui/src/app/services/system.service.ts +620 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.spec.ts +513 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.ts +1015 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.spec.ts +85 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.ts +662 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts +70 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.ts +383 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.spec.ts +107 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.ts +123 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.spec.ts +92 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.ts +116 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.spec.ts +640 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.ts +1021 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.spec.ts +375 -0
- package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.ts +1419 -0
- package/artemis-main/apps/showcase_ui/src/index.html +37 -0
- package/artemis-main/apps/showcase_ui/src/main.ts +22 -0
- package/artemis-main/apps/showcase_ui/src/styles.scss +60 -0
- package/artemis-main/apps/showcase_ui/tsconfig.app.json +23 -0
- package/artemis-main/apps/showcase_ui/tsconfig.json +27 -0
- package/artemis-main/apps/showcase_ui/tsconfig.spec.json +23 -0
- package/artemis-main/artemis/__init__.py +44 -0
- package/artemis-main/artemis/__main__.py +18 -0
- package/artemis-main/artemis/_legacy_imports.py +94 -0
- package/artemis-main/artemis/_version.py +30 -0
- package/artemis-main/artemis/agents/__init__.py +17 -0
- package/artemis-main/artemis/agents/checker/checker.json +9 -0
- package/artemis-main/artemis/agents/checker/checker.py +859 -0
- package/artemis-main/artemis/agents/diagnoser/diagnoser.json +23 -0
- package/artemis-main/artemis/agents/diagnoser/diagnoser.py +608 -0
- package/artemis-main/artemis/agents/explorer/constants.py +52 -0
- package/artemis-main/artemis/agents/explorer/explorer.json +57 -0
- package/artemis-main/artemis/agents/explorer/explorer.py +473 -0
- package/artemis-main/artemis/agents/explorer/geometry.py +73 -0
- package/artemis-main/artemis/agents/explorer/native_runner.py +878 -0
- package/artemis-main/artemis/agents/explorer/perception_tools.py +632 -0
- package/artemis-main/artemis/agents/explorer/run_setup.py +403 -0
- package/artemis-main/artemis/agents/explorer/screen_index.py +266 -0
- package/artemis-main/artemis/agents/explorer/tiers.py +110 -0
- package/artemis-main/artemis/agents/explorer/tool_declarations.py +394 -0
- package/artemis-main/artemis/agents/explorer/universal_runner.py +317 -0
- package/artemis-main/artemis/agents/flash/context_compressor.py +452 -0
- package/artemis-main/artemis/agents/flash/flash_runner.md +51 -0
- package/artemis-main/artemis/agents/flash/flash_summarizer.md +53 -0
- package/artemis-main/artemis/agents/flash/flash_summarizer_single.md +54 -0
- package/artemis-main/artemis/agents/flash/runner.py +1167 -0
- package/artemis-main/artemis/agents/flash/summarizer.py +511 -0
- package/artemis-main/artemis/agents/history_analyzer/history_analyzer.md +8 -0
- package/artemis-main/artemis/agents/history_analyzer/history_analyzer.py +182 -0
- package/artemis-main/artemis/agents/image_processor/image_processor.md +74 -0
- package/artemis-main/artemis/agents/image_processor/image_processor.py +322 -0
- package/artemis-main/artemis/agents/log_analyzer/log_analyzer.md +15 -0
- package/artemis-main/artemis/agents/log_analyzer/log_analyzer.py +403 -0
- package/artemis-main/artemis/agents/log_analyzer/log_reader_sub_agent.md +8 -0
- package/artemis-main/artemis/agents/log_analyzer/output_analyzer.md +11 -0
- package/artemis-main/artemis/agents/log_analyzer/output_analyzer.py +163 -0
- package/artemis-main/artemis/agents/object_detector/object_detector.json +9 -0
- package/artemis-main/artemis/agents/object_detector/object_detector.py +211 -0
- package/artemis-main/artemis/agents/operator/operator.json +3 -0
- package/artemis-main/artemis/agents/operator/operator.py +1394 -0
- package/artemis-main/artemis/agents/operator/prompts.py +1064 -0
- package/artemis-main/artemis/agents/outputter/outputter.md +36 -0
- package/artemis-main/artemis/agents/outputter/outputter.py +552 -0
- package/artemis-main/artemis/agents/planner/planner.json +32 -0
- package/artemis-main/artemis/agents/planner/planner.py +436 -0
- package/artemis-main/artemis/agents/prompt_assembly.py +79 -0
- package/artemis-main/artemis/agents/summarizer/summarizer.py +190 -0
- package/artemis-main/artemis/agents/validator/action_execution.py +98 -0
- package/artemis-main/artemis/agents/validator/categories.py +33 -0
- package/artemis-main/artemis/agents/validator/execution_loop.py +488 -0
- package/artemis-main/artemis/agents/validator/incidents.py +120 -0
- package/artemis-main/artemis/agents/validator/pixel_safety_net.md +15 -0
- package/artemis-main/artemis/agents/validator/precondition_pixel.py +320 -0
- package/artemis-main/artemis/agents/validator/precondition_xml.py +672 -0
- package/artemis-main/artemis/agents/validator/tool_declarations.py +332 -0
- package/artemis-main/artemis/agents/validator/validator.py +188 -0
- package/artemis-main/artemis/agents/video_analyzer/__init__.py +15 -0
- package/artemis-main/artemis/agents/video_analyzer/audio_native.py +543 -0
- package/artemis-main/artemis/agents/video_analyzer/blackboard.py +821 -0
- package/artemis-main/artemis/agents/video_analyzer/chunk_agentic.py +455 -0
- package/artemis-main/artemis/agents/video_analyzer/chunk_conversation.py +491 -0
- package/artemis-main/artemis/agents/video_analyzer/chunk_native.py +437 -0
- package/artemis-main/artemis/agents/video_analyzer/conflict_resolution.py +137 -0
- package/artemis-main/artemis/agents/video_analyzer/gemini_files.py +162 -0
- package/artemis-main/artemis/agents/video_analyzer/native_coordinator.py +541 -0
- package/artemis-main/artemis/agents/video_analyzer/reliability.py +128 -0
- package/artemis-main/artemis/agents/video_analyzer/universal_engine.py +487 -0
- package/artemis-main/artemis/agents/video_analyzer/universal_tools.py +323 -0
- package/artemis-main/artemis/agents/video_analyzer/video_analyzer.md +51 -0
- package/artemis-main/artemis/agents/video_analyzer/video_analyzer.py +875 -0
- package/artemis-main/artemis/agents/video_analyzer/video_sub_agent.md +15 -0
- package/artemis-main/artemis/agents/video_analyzer/video_sub_agent_audio.md +12 -0
- package/artemis-main/artemis/clients/accessibility_client.py +438 -0
- package/artemis-main/artemis/clients/screen_client_factory.py +403 -0
- package/artemis-main/artemis/config/__init__.py +309 -0
- package/artemis-main/artemis/config/agent.py +1098 -0
- package/artemis-main/artemis/config/constants.py +151 -0
- package/artemis-main/artemis/config/core/__init__.py +24 -0
- package/artemis-main/artemis/config/core/engine.py +118 -0
- package/artemis-main/artemis/config/core/interpolator.py +78 -0
- package/artemis-main/artemis/config/llm.py +267 -0
- package/artemis-main/artemis/config/paths.py +244 -0
- package/artemis-main/artemis/config/runtime.py +197 -0
- package/artemis-main/artemis/config/settings.py +315 -0
- package/artemis-main/artemis/constants.py +47 -0
- package/artemis-main/artemis/context.py +289 -0
- package/artemis-main/artemis/controllers/__init__.py +41 -0
- package/artemis-main/artemis/controllers/controller_factory.py +41 -0
- package/artemis-main/artemis/controllers/device_controller.py +29 -0
- package/artemis-main/artemis/controllers/types.py +37 -0
- package/artemis-main/artemis/controllers/unified_controller.py +649 -0
- package/artemis-main/artemis/core/__init__.py +21 -0
- package/artemis-main/artemis/core/diagnostics/__init__.py +90 -0
- package/artemis-main/artemis/core/diagnostics/adb_keys.py +270 -0
- package/artemis-main/artemis/core/diagnostics/adb_server_connection.py +330 -0
- package/artemis-main/artemis/core/diagnostics/device_smoke.py +364 -0
- package/artemis-main/artemis/core/diagnostics/emulator_manager.py +501 -0
- package/artemis-main/artemis/core/diagnostics/engine.py +438 -0
- package/artemis-main/artemis/core/diagnostics/hierarchy_parity.py +216 -0
- package/artemis-main/artemis/core/diagnostics/probes/adb_probe.py +887 -0
- package/artemis-main/artemis/core/diagnostics/probes/base.py +45 -0
- package/artemis-main/artemis/core/diagnostics/probes/credentials_probe.py +296 -0
- package/artemis-main/artemis/core/diagnostics/probes/host_probe.py +427 -0
- package/artemis-main/artemis/core/diagnostics/probes/runtime_probe.py +169 -0
- package/artemis-main/artemis/core/diagnostics/probes/toolchain_probe.py +139 -0
- package/artemis-main/artemis/core/diagnostics/readiness.py +83 -0
- package/artemis-main/artemis/core/diagnostics/schema.py +118 -0
- package/artemis-main/artemis/core/tool_declaration.py +43 -0
- package/artemis-main/artemis/core/tool_failure.py +56 -0
- package/artemis-main/artemis/data_engine/context_vars.py +24 -0
- package/artemis-main/artemis/data_engine/engine.py +1615 -0
- package/artemis-main/artemis/data_engine/history_reader.py +142 -0
- package/artemis-main/artemis/data_engine/models.py +131 -0
- package/artemis-main/artemis/data_engine/storage.py +1245 -0
- package/artemis-main/artemis/data_engine/trace.py +727 -0
- package/artemis-main/artemis/drivers/__init__.py +48 -0
- package/artemis-main/artemis/drivers/android/adb_driver.py +507 -0
- package/artemis-main/artemis/drivers/android/hierarchy.py +64 -0
- package/artemis-main/artemis/drivers/android/input_ime.py +120 -0
- package/artemis-main/artemis/drivers/android/recorder.py +57 -0
- package/artemis-main/artemis/drivers/base.py +290 -0
- package/artemis-main/artemis/drivers/cloud/cloud_driver.py +117 -0
- package/artemis-main/artemis/drivers/factory.py +80 -0
- package/artemis-main/artemis/drivers/mock/mock_driver.py +198 -0
- package/artemis-main/artemis/drivers/types.py +67 -0
- package/artemis-main/artemis/graph/checkpoints.py +1243 -0
- package/artemis-main/artemis/graph/graph.py +1055 -0
- package/artemis-main/artemis/graph/perception.py +234 -0
- package/artemis-main/artemis/graph/state.py +151 -0
- package/artemis-main/artemis/graph/visibility.py +238 -0
- package/artemis-main/artemis/interfaces/cli/__init__.py +19 -0
- package/artemis-main/artemis/interfaces/cli/commands/__init__.py +15 -0
- package/artemis-main/artemis/interfaces/cli/commands/batch.py +278 -0
- package/artemis-main/artemis/interfaces/cli/commands/doctor.py +468 -0
- package/artemis-main/artemis/interfaces/cli/commands/helper.py +226 -0
- package/artemis-main/artemis/interfaces/cli/commands/init.py +193 -0
- package/artemis-main/artemis/interfaces/cli/commands/mcp.py +862 -0
- package/artemis-main/artemis/interfaces/cli/commands/run.py +463 -0
- package/artemis-main/artemis/interfaces/cli/commands/server.py +151 -0
- package/artemis-main/artemis/interfaces/cli/commands/server_lifecycle.py +328 -0
- package/artemis-main/artemis/interfaces/cli/commands/trace.py +111 -0
- package/artemis-main/artemis/interfaces/cli/commands/ui.py +404 -0
- package/artemis-main/artemis/interfaces/cli/main.py +109 -0
- package/artemis-main/artemis/interfaces/sdk/__init__.py +31 -0
- package/artemis-main/artemis/interfaces/sdk/client.py +19 -0
- package/artemis-main/artemis/interfaces/sdk/task.py +72 -0
- package/artemis-main/artemis/llm/__init__.py +25 -0
- package/artemis-main/artemis/llm/fake_model.py +179 -0
- package/artemis-main/artemis/llm/google/__init__.py +57 -0
- package/artemis-main/artemis/llm/google/provider.py +185 -0
- package/artemis-main/artemis/llm/google/usage.py +148 -0
- package/artemis-main/artemis/llm/parser.py +32 -0
- package/artemis-main/artemis/llm/reliability.py +267 -0
- package/artemis-main/artemis/llm/router.py +389 -0
- package/artemis-main/artemis/llm/schemas.py +36 -0
- package/artemis-main/artemis/llm/structured.py +196 -0
- package/artemis-main/artemis/main.py +58 -0
- package/artemis-main/artemis/mcp/__init__.py +20 -0
- package/artemis-main/artemis/mcp/action_executor.py +760 -0
- package/artemis-main/artemis/mcp/action_manifest.py +320 -0
- package/artemis-main/artemis/mcp/action_names.py +172 -0
- package/artemis-main/artemis/mcp/action_server.py +202 -0
- package/artemis-main/artemis/mcp/action_session.py +245 -0
- package/artemis-main/artemis/mcp/action_specs.py +868 -0
- package/artemis-main/artemis/mcp/action_types.py +86 -0
- package/artemis-main/artemis/mcp/actuators/__init__.py +21 -0
- package/artemis-main/artemis/mcp/actuators/adb.py +414 -0
- package/artemis-main/artemis/mcp/actuators/base.py +113 -0
- package/artemis-main/artemis/mcp/actuators/mock.py +70 -0
- package/artemis-main/artemis/mcp/adb_server.py +490 -0
- package/artemis-main/artemis/mcp/observation.py +133 -0
- package/artemis-main/artemis/mcp/xml_search_server.py +297 -0
- package/artemis-main/artemis/memory/__init__.py +90 -0
- package/artemis-main/artemis/memory/chunking.py +1843 -0
- package/artemis-main/artemis/memory/context_policy.py +226 -0
- package/artemis-main/artemis/memory/step_capsule.md +73 -0
- package/artemis-main/artemis/memory/step_memory.py +281 -0
- package/artemis-main/artemis/memory/transcript.py +798 -0
- package/artemis-main/artemis/platform/__init__.py +61 -0
- package/artemis-main/artemis/platform/base.py +104 -0
- package/artemis-main/artemis/platform/darwin.py +184 -0
- package/artemis-main/artemis/platform/linux.py +207 -0
- package/artemis-main/artemis/platform/windows.py +193 -0
- package/artemis-main/artemis/resources/__init__.py +46 -0
- package/artemis-main/artemis/runtime/__init__.py +108 -0
- package/artemis-main/artemis/runtime/adb_endpoint.py +173 -0
- package/artemis-main/artemis/runtime/awake_lease.py +283 -0
- package/artemis-main/artemis/runtime/awake_service.py +343 -0
- package/artemis-main/artemis/runtime/cancel_requests.py +254 -0
- package/artemis-main/artemis/runtime/daemon_client.py +422 -0
- package/artemis-main/artemis/runtime/device_lock.py +1013 -0
- package/artemis-main/artemis/runtime/device_pool.py +478 -0
- package/artemis-main/artemis/runtime/helper_manager.py +1030 -0
- package/artemis-main/artemis/runtime/process_probe.py +98 -0
- package/artemis-main/artemis/runtime/server_lifecycle.py +435 -0
- package/artemis-main/artemis/runtime/supervisor.py +121 -0
- package/artemis-main/artemis/runtime/trace_store.py +375 -0
- package/artemis-main/artemis/sdk/__init__.py +26 -0
- package/artemis-main/artemis/sdk/agent.py +485 -0
- package/artemis-main/artemis/sdk/builders/__init__.py +29 -0
- package/artemis-main/artemis/sdk/builders/agent_config_builder.py +474 -0
- package/artemis-main/artemis/sdk/constants.py +15 -0
- package/artemis-main/artemis/sdk/run_outcome.py +58 -0
- package/artemis-main/artemis/sdk/types/__init__.py +61 -0
- package/artemis-main/artemis/sdk/types/agent.py +89 -0
- package/artemis-main/artemis/sdk/utils.py +28 -0
- package/artemis-main/artemis/services/llm.py +1040 -0
- package/artemis-main/artemis/services/token_meter.py +267 -0
- package/artemis-main/artemis/telemetry/__init__.py +35 -0
- package/artemis-main/artemis/telemetry/models.py +64 -0
- package/artemis-main/artemis/telemetry/replay.py +34 -0
- package/artemis-main/artemis/telemetry/storage/json_storage.py +47 -0
- package/artemis-main/artemis/telemetry/tracer.py +85 -0
- package/artemis-main/artemis/toolchain/__init__.py +52 -0
- package/artemis-main/artemis/toolchain/descriptors.py +92 -0
- package/artemis-main/artemis/toolchain/resolver.py +185 -0
- package/artemis-main/artemis/tools/base.py +232 -0
- package/artemis-main/artemis/tools/command_tool.py +1240 -0
- package/artemis-main/artemis/tools/committee_prompts.json +5 -0
- package/artemis-main/artemis/tools/committee_tool.py +422 -0
- package/artemis-main/artemis/tools/diagnoser_submit_answer_tool.py +87 -0
- package/artemis-main/artemis/tools/diagnostic_tool.py +120 -0
- package/artemis-main/artemis/tools/explorer_tool.py +581 -0
- package/artemis-main/artemis/tools/history/__init__.py +398 -0
- package/artemis-main/artemis/tools/history/replay.py +120 -0
- package/artemis-main/artemis/tools/history/screenshot.py +139 -0
- package/artemis-main/artemis/tools/history/search.py +563 -0
- package/artemis-main/artemis/tools/image_processor_tool.py +124 -0
- package/artemis-main/artemis/tools/index.py +47 -0
- package/artemis-main/artemis/tools/log_tool.py +108 -0
- package/artemis-main/artemis/tools/mobile/launch_app.py +132 -0
- package/artemis-main/artemis/tools/mobile/log_utils.py +138 -0
- package/artemis-main/artemis/tools/mobile/ocr.py +202 -0
- package/artemis-main/artemis/tools/mobile/read_hierarchy.py +108 -0
- package/artemis-main/artemis/tools/mobile/read_logs.py +116 -0
- package/artemis-main/artemis/tools/mobile/search_logs.py +260 -0
- package/artemis-main/artemis/tools/object_detection_tool.py +244 -0
- package/artemis-main/artemis/tools/scratchpad.py +819 -0
- package/artemis-main/artemis/tools/system/adb_shell.py +31 -0
- package/artemis-main/artemis/tools/tool_wrapper.py +270 -0
- package/artemis-main/artemis/tools/video_tool.py +261 -0
- package/artemis-main/artemis/tools/wait_tool.py +97 -0
- package/artemis-main/artemis/utils/app_launch_utils.py +207 -0
- package/artemis-main/artemis/utils/coordinates.py +606 -0
- package/artemis-main/artemis/utils/credentials_validator.py +201 -0
- package/artemis-main/artemis/utils/cv_canvas.py +189 -0
- package/artemis-main/artemis/utils/cython_compat.py +45 -0
- package/artemis-main/artemis/utils/element_hit_test.py +80 -0
- package/artemis-main/artemis/utils/image_diff.py +335 -0
- package/artemis-main/artemis/utils/image_hash.py +80 -0
- package/artemis-main/artemis/utils/notes.py +470 -0
- package/artemis-main/artemis/utils/ocr_api.py +105 -0
- package/artemis-main/artemis/utils/ocr_xml_fusion.py +318 -0
- package/artemis-main/artemis/utils/plan_grammar.py +513 -0
- package/artemis-main/artemis/utils/python_executor.py +213 -0
- package/artemis-main/artemis/utils/startup_progress.py +60 -0
- package/artemis-main/artemis/utils/task_tree.py +1174 -0
- package/artemis-main/artemis/utils/text.py +37 -0
- package/artemis-main/artemis/utils/ui_filter.py +651 -0
- package/artemis-main/artemis/utils/video.py +685 -0
- package/artemis-main/artemis/utils/visualization.py +802 -0
- package/artemis-main/config/artemis.example.jsonc +12 -0
- package/artemis-main/mcp_server/README.md +111 -0
- package/artemis-main/mcp_server/__init__.py +21 -0
- package/artemis-main/mcp_server/__main__.py +20 -0
- package/artemis-main/mcp_server/background/__init__.py +15 -0
- package/artemis-main/mcp_server/background/task_runner.py +453 -0
- package/artemis-main/mcp_server/base.py +49 -0
- package/artemis-main/mcp_server/notifiers/__init__.py +74 -0
- package/artemis-main/mcp_server/notifiers/agentapi.py +289 -0
- package/artemis-main/mcp_server/notifiers/base.py +45 -0
- package/artemis-main/mcp_server/notifiers/composite.py +87 -0
- package/artemis-main/mcp_server/notifiers/desktop.py +108 -0
- package/artemis-main/mcp_server/notifiers/file.py +69 -0
- package/artemis-main/mcp_server/notifiers/script.py +90 -0
- package/artemis-main/mcp_server/notifiers/webhook.py +87 -0
- package/artemis-main/mcp_server/rules.md +68 -0
- package/artemis-main/mcp_server/server.py +106 -0
- package/artemis-main/mcp_server/tools/__init__.py +29 -0
- package/artemis-main/mcp_server/tools/device_state.py +107 -0
- package/artemis-main/mcp_server/tools/diagnose.py +1249 -0
- package/artemis-main/mcp_server/tools/inspect_trace.py +394 -0
- package/artemis-main/mcp_server/tools/task_manager.py +627 -0
- package/artemis-main/mcp_server/tools/task_runner.py +548 -0
- package/artemis-main/mcp_server/utils/__init__.py +15 -0
- package/artemis-main/mcp_server/utils/device_utils.py +180 -0
- package/artemis-main/mcp_server/utils/env_utils.py +65 -0
- package/artemis-main/packages/artemis-accessibility-helper/ArtemisAccessibilityHelper.apk +0 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/build.gradle.kts +35 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/AndroidManifest.xml +49 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/A11yNode.java +274 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/ArtemisAccessibilityService.java +227 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/CommandServer.java +463 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/DisplayUtils.java +111 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/GestureController.java +232 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/HierarchyDumper.java +832 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenReceiver.java +36 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenStore.java +38 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/XmlUtils.java +102 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/values/strings.xml +4 -0
- package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/xml/accessibility_service_config.xml +10 -0
- package/artemis-main/packages/artemis-accessibility-helper/build.gradle.kts +3 -0
- package/artemis-main/packages/artemis-accessibility-helper/build_apk.sh +215 -0
- package/artemis-main/packages/artemis-accessibility-helper/debug.keystore +0 -0
- package/artemis-main/packages/artemis-accessibility-helper/gradle.properties +2 -0
- package/artemis-main/packages/artemis-accessibility-helper/helper_manifest.json +7 -0
- package/artemis-main/packages/artemis-accessibility-helper/settings.gradle.kts +17 -0
- package/artemis-main/packages/artemis-client/DESIGN.md +89 -0
- package/artemis-main/packages/artemis-client/README.md +112 -0
- package/artemis-main/packages/artemis-client/examples/basic.py +30 -0
- package/artemis-main/packages/artemis-client/pyproject.toml +36 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/__init__.py +45 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/client.py +401 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/errors.py +66 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/models.py +212 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/py.typed +1 -0
- package/artemis-main/packages/artemis-client/src/artemis_client/transport.py +134 -0
- package/artemis-main/packages/artemis-client/tests/test_client.py +289 -0
- package/artemis-main/packages/artemis-client/tests/test_transport.py +85 -0
- package/artemis-main/pyproject.toml +259 -0
- package/artemis-main/pyright-core.json +17 -0
- package/artemis-main/scripts/check_dependency_sources.py +68 -0
- package/artemis-main/scripts/install_deps.ps1 +520 -0
- package/artemis-main/scripts/install_deps.sh +533 -0
- package/artemis-main/scripts/quality_ratchet.py +97 -0
- package/artemis-main/scripts/real_device_video_acceptance.py +483 -0
- package/artemis-main/scripts/run_edge_case_part.py +327 -0
- package/artemis-main/scripts/run_ui.py +242 -0
- package/artemis-main/scripts/start.ps1 +500 -0
- package/artemis-main/scripts/test_all_edge_cases.py +269 -0
- package/artemis-main/scripts/verify_concurrency_and_devices.py +385 -0
- package/artemis-main/setup.py +164 -0
- package/artemis-main/start.bat +35 -0
- package/artemis-main/start.sh +423 -0
- package/artemis-main/third_party/mobile_use/LICENSE +190 -0
- package/artemis-main/third_party/mobile_use/METADATA +27 -0
- package/artemis-main/third_party/mobile_use/NOTICE +12 -0
- package/artemis-main/third_party/mobile_use/__init__.py +19 -0
- package/artemis-main/third_party/mobile_use/agents/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/agents/hopper/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/agents/hopper/hopper.md +22 -0
- package/artemis-main/third_party/mobile_use/agents/hopper/hopper.py +80 -0
- package/artemis-main/third_party/mobile_use/clients/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/clients/ui_automator_client.py +482 -0
- package/artemis-main/third_party/mobile_use/config/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/config/llm.py +183 -0
- package/artemis-main/third_party/mobile_use/config/output.py +184 -0
- package/artemis-main/third_party/mobile_use/context.py +119 -0
- package/artemis-main/third_party/mobile_use/controllers/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/controllers/platform_specific_commands_controller.py +151 -0
- package/artemis-main/third_party/mobile_use/controllers/types.py +92 -0
- package/artemis-main/third_party/mobile_use/controllers/unified_controller.py +183 -0
- package/artemis-main/third_party/mobile_use/graph.py +54 -0
- package/artemis-main/third_party/mobile_use/llm_service.py +193 -0
- package/artemis-main/third_party/mobile_use/main.py +130 -0
- package/artemis-main/third_party/mobile_use/sdk/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/sdk/agent.py +1060 -0
- package/artemis-main/third_party/mobile_use/sdk/builders/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/sdk/builders/agent_config_builder.py +225 -0
- package/artemis-main/third_party/mobile_use/sdk/builders/index.py +33 -0
- package/artemis-main/third_party/mobile_use/sdk/builders/task_request_builder.py +243 -0
- package/artemis-main/third_party/mobile_use/sdk/types/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/sdk/types/agent.py +98 -0
- package/artemis-main/third_party/mobile_use/sdk/types/exceptions.py +109 -0
- package/artemis-main/third_party/mobile_use/sdk/types/task.py +234 -0
- package/artemis-main/third_party/mobile_use/testing.py +59 -0
- package/artemis-main/third_party/mobile_use/tools/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/tools/index.py +44 -0
- package/artemis-main/third_party/mobile_use/tools/mobile/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/tools/mobile/launch_app.py +89 -0
- package/artemis-main/third_party/mobile_use/tools/tool_wrapper.py +52 -0
- package/artemis-main/third_party/mobile_use/utils/__init__.py +13 -0
- package/artemis-main/third_party/mobile_use/utils/app_launch_utils.py +217 -0
- package/artemis-main/third_party/mobile_use/utils/cli_helpers.py +60 -0
- package/artemis-main/third_party/mobile_use/utils/decorators.py +158 -0
- package/artemis-main/third_party/mobile_use/utils/file.py +31 -0
- package/artemis-main/third_party/mobile_use/utils/logger.py +216 -0
- package/artemis-main/third_party/mobile_use/utils/media.py +213 -0
- package/artemis-main/third_party/mobile_use/utils/shell_utils.py +39 -0
- package/artemis-main/third_party/mobile_use/utils/video.py +398 -0
- package/artemis-main/uv.lock +4908 -0
- package/bin/android-midscene-automation.js +1 -5
- package/bin/artemis-config.mjs +15 -0
- package/bin/artemis-embedded.py +56 -0
- package/bin/start-artemis.mjs +30 -0
- package/bin/start-dev.mjs +112 -0
- package/bin/test_artemis_embedded.py +44 -0
- package/package.json +10 -8
- package/server/artemis.ts +34 -0
- package/server/http-api.ts +13 -1
- package/src/App.vue +72 -23
- package/src/api.ts +5 -0
- package/src/appium-recorder/AppiumPage.vue +1 -1
- package/src/appium-recorder/components/ComponentInspector.vue +1 -1
- package/src/appium-recorder/components/FlowNodeSearch.vue +3 -3
- package/src/appium-recorder/components/ImageCheckDialog.vue +3 -3
- package/src/appium-recorder/components/RecorderWorkspace.vue +4 -4
- package/src/appium-recorder/flow-appearance.ts +4 -4
- package/src/components/AppSidebar.vue +8 -7
- package/src/components/MidsceneMaintenanceNotice.vue +17 -0
- package/src/components/analytics/AnalysisCharts.vue +4 -4
- package/src/components/analytics/ReportAnalysis.vue +1 -1
- package/src/components/generator/TestCaseFileUpload.vue +1 -1
- package/src/components/help/HelpCenter.vue +56 -37
- package/src/pages/AiGeneratorPage.vue +1 -1
- package/src/pages/ArtemisPage.vue +72 -0
- package/src/pages/ConfigPage.vue +18 -19
- package/src/style.css +369 -186
- package/src/types.ts +1 -1
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Builder for AgentConfig objects using a fluent interface."""
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
from typing import Any, cast
|
|
19
|
+
|
|
20
|
+
from artemis.config import (
|
|
21
|
+
ExplorerVersion,
|
|
22
|
+
checker_overrides_for_level,
|
|
23
|
+
load_agent_config,
|
|
24
|
+
settings,
|
|
25
|
+
)
|
|
26
|
+
from artemis.context import DevicePlatform
|
|
27
|
+
from artemis.sdk.types.agent import AgentConfig, ServerConfig
|
|
28
|
+
from artemis.utils.video import detect_video_tools_enabled
|
|
29
|
+
from third_party.mobile_use.sdk.builders.agent_config_builder import AgentConfigBuilderBase
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AgentConfigBuilder(AgentConfigBuilderBase):
|
|
33
|
+
"""Artemis AgentConfig builder; see :class:`AgentConfigBuilderBase` for usage."""
|
|
34
|
+
|
|
35
|
+
config_class = AgentConfig
|
|
36
|
+
|
|
37
|
+
def __init__(self):
|
|
38
|
+
"""Initialize an empty AgentConfigBuilder with Artemis defaults."""
|
|
39
|
+
super().__init__(servers=get_default_servers())
|
|
40
|
+
self._video_recording_tools_enabled: bool = detect_video_tools_enabled()
|
|
41
|
+
self._force_web_accessibility: bool = False
|
|
42
|
+
self._disable_checker: bool = False
|
|
43
|
+
self._concurrency_mode: str = "per_device"
|
|
44
|
+
self._max_concurrency: int | None = None
|
|
45
|
+
|
|
46
|
+
agent_cfg = load_agent_config()
|
|
47
|
+
self._explorer = agent_cfg.explorer
|
|
48
|
+
self._explorer_versions = agent_cfg.explorer_versions
|
|
49
|
+
self._denylisted_tools = agent_cfg.denylisted_tools
|
|
50
|
+
self._video_analyzer = agent_cfg.video_analyzer
|
|
51
|
+
self._enable_video_ledger = agent_cfg.video_analyzer.enable_ledger
|
|
52
|
+
if agent_cfg.video_analyzer.enabled is not None:
|
|
53
|
+
self._video_recording_tools_enabled = agent_cfg.video_analyzer.enabled
|
|
54
|
+
else:
|
|
55
|
+
self._video_recording_tools_enabled = detect_video_tools_enabled()
|
|
56
|
+
self._disable_planner_validation = not agent_cfg.planner_validation.enabled
|
|
57
|
+
self._enable_committee = agent_cfg.committee.enabled
|
|
58
|
+
self._committee_debate_rounds = agent_cfg.committee.debate_rounds
|
|
59
|
+
self._disable_checker = not agent_cfg.checker.enabled
|
|
60
|
+
self._checker_max_iterations = agent_cfg.checker.max_iterations
|
|
61
|
+
self._disable_midway_checks = not agent_cfg.checker.midway_checks
|
|
62
|
+
self._disable_final_check = not agent_cfg.checker.final_check
|
|
63
|
+
self._final_check_max_attempts = agent_cfg.checker.final_check_max_attempts
|
|
64
|
+
self._checkpoint_max_repairs = agent_cfg.checker.checkpoint_max_repairs
|
|
65
|
+
self._max_concurrent_checkpoints = agent_cfg.checker.max_concurrent_checkpoints
|
|
66
|
+
self._checkpoint_timeout = agent_cfg.checker.checkpoint_timeout
|
|
67
|
+
self._settlement_timeout = agent_cfg.checker.settlement_timeout
|
|
68
|
+
self._assert_failure_policy = agent_cfg.checker.assert_failure_policy
|
|
69
|
+
self._disable_device_probes = not agent_cfg.checker.device_probes
|
|
70
|
+
self._outputter = agent_cfg.outputter
|
|
71
|
+
self._disable_outputter = not agent_cfg.outputter.enabled
|
|
72
|
+
self._flash = agent_cfg.flash
|
|
73
|
+
self._pro = agent_cfg.pro
|
|
74
|
+
|
|
75
|
+
def for_device_serial(self, device_serial: str) -> "AgentConfigBuilder":
|
|
76
|
+
"""Target a specific Android device by its ADB serial number."""
|
|
77
|
+
return self.for_device(DevicePlatform.ANDROID, device_serial)
|
|
78
|
+
|
|
79
|
+
def with_concurrency_mode(self, mode: str) -> "AgentConfigBuilder":
|
|
80
|
+
"""Configure concurrency mode: 'global' (1 task globally) or 'per_device' (1 task per device)."""
|
|
81
|
+
self._concurrency_mode = str(mode).strip().lower()
|
|
82
|
+
return self
|
|
83
|
+
|
|
84
|
+
def with_max_concurrency(self, max_concurrency: int) -> "AgentConfigBuilder":
|
|
85
|
+
"""Configure max concurrent tasks limit."""
|
|
86
|
+
self._max_concurrency = max_concurrency
|
|
87
|
+
return self
|
|
88
|
+
|
|
89
|
+
def with_video_recording_tools(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
90
|
+
"""Enable or disable video recording tools.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
enabled: Whether to enable video recording tools
|
|
94
|
+
"""
|
|
95
|
+
self._video_recording_tools_enabled = enabled
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def with_web_accessibility(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
99
|
+
"""Enable or disable forcing web accessibility for WebViews.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
enabled: Whether to force web accessibility
|
|
103
|
+
"""
|
|
104
|
+
self._force_web_accessibility = enabled
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
def with_disable_checker(self, disable: bool = True) -> "AgentConfigBuilder":
|
|
108
|
+
"""Temporarily disable the background Checker task (useful for debugging).
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
disable: Whether to disable the checker
|
|
112
|
+
"""
|
|
113
|
+
self._disable_checker = disable
|
|
114
|
+
return self
|
|
115
|
+
|
|
116
|
+
def with_checker(
|
|
117
|
+
self,
|
|
118
|
+
enabled: bool = True,
|
|
119
|
+
max_iterations: int | None = None,
|
|
120
|
+
midway_checks: bool | None = None,
|
|
121
|
+
final_check: bool | None = None,
|
|
122
|
+
final_check_max_attempts: int | None = None,
|
|
123
|
+
checkpoint_max_repairs: int | None = None,
|
|
124
|
+
max_concurrent_checkpoints: int | None = None,
|
|
125
|
+
checkpoint_timeout: float | None = None,
|
|
126
|
+
settlement_timeout: float | None = None,
|
|
127
|
+
assert_failure_policy: str | None = None,
|
|
128
|
+
device_probes: bool | None = None,
|
|
129
|
+
) -> "AgentConfigBuilder":
|
|
130
|
+
"""Configure plan-driven checkpoint verification and the final review.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
enabled: Master switch (compat alias); False disables both gates
|
|
134
|
+
max_iterations: Optional maximum iterations for Checker reasoning (1-50)
|
|
135
|
+
midway_checks: Whether plan-declared midway checkpoints run
|
|
136
|
+
final_check: Whether the exit final review runs
|
|
137
|
+
final_check_max_attempts: Max final-review attempts before a blocked exit
|
|
138
|
+
checkpoint_max_repairs: Per-checkpoint verify-fail repair quota
|
|
139
|
+
max_concurrent_checkpoints: Concurrency cap for checkpoint attempts
|
|
140
|
+
checkpoint_timeout: Per-attempt timeout in seconds
|
|
141
|
+
settlement_timeout: Aggregate exit-settlement timeout in seconds
|
|
142
|
+
assert_failure_policy: 'continue' or 'halt' on assert failures
|
|
143
|
+
device_probes: Whether Checker read-only device probes are registered
|
|
144
|
+
"""
|
|
145
|
+
self._disable_checker = not enabled
|
|
146
|
+
if max_iterations is not None:
|
|
147
|
+
self._checker_max_iterations = max_iterations
|
|
148
|
+
if midway_checks is not None:
|
|
149
|
+
self._disable_midway_checks = not midway_checks
|
|
150
|
+
if final_check is not None:
|
|
151
|
+
self._disable_final_check = not final_check
|
|
152
|
+
if final_check_max_attempts is not None:
|
|
153
|
+
self._final_check_max_attempts = final_check_max_attempts
|
|
154
|
+
if checkpoint_max_repairs is not None:
|
|
155
|
+
self._checkpoint_max_repairs = checkpoint_max_repairs
|
|
156
|
+
if max_concurrent_checkpoints is not None:
|
|
157
|
+
self._max_concurrent_checkpoints = max_concurrent_checkpoints
|
|
158
|
+
if checkpoint_timeout is not None:
|
|
159
|
+
self._checkpoint_timeout = checkpoint_timeout
|
|
160
|
+
if settlement_timeout is not None:
|
|
161
|
+
self._settlement_timeout = settlement_timeout
|
|
162
|
+
if assert_failure_policy is not None:
|
|
163
|
+
self._assert_failure_policy = assert_failure_policy
|
|
164
|
+
if device_probes is not None:
|
|
165
|
+
self._disable_device_probes = not device_probes
|
|
166
|
+
return self
|
|
167
|
+
|
|
168
|
+
def with_verification_level(self, level: str) -> "AgentConfigBuilder":
|
|
169
|
+
"""Apply a coarse Checker preset (the ``--verification-level`` knob).
|
|
170
|
+
|
|
171
|
+
Presets are defined once in :data:`artemis.config.VERIFICATION_LEVEL_PRESETS`:
|
|
172
|
+
``off`` (no Checker), ``final`` (exit review only, the factory default),
|
|
173
|
+
``checkpoints`` (every plan checkpoint + exit review) and ``strict``
|
|
174
|
+
(checkpoints with a larger repair budget; a failed assert halts).
|
|
175
|
+
Fields the preset leaves unspecified keep their current values, so an
|
|
176
|
+
explicit :meth:`with_checker` call afterwards still wins.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
level: One of ``off``, ``final``, ``checkpoints`` or ``strict``
|
|
180
|
+
(case-insensitive, surrounding whitespace ignored).
|
|
181
|
+
|
|
182
|
+
Raises:
|
|
183
|
+
ValueError: when ``level`` is not a known preset.
|
|
184
|
+
"""
|
|
185
|
+
return self.with_checker(**checker_overrides_for_level(level))
|
|
186
|
+
|
|
187
|
+
def with_midway_checks(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
188
|
+
"""Enable or disable plan-declared midway checkpoints."""
|
|
189
|
+
self._disable_midway_checks = not enabled
|
|
190
|
+
return self
|
|
191
|
+
|
|
192
|
+
def with_final_check(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
193
|
+
"""Enable or disable the exit final review."""
|
|
194
|
+
self._disable_final_check = not enabled
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
def with_disable_planner_validation(self, disable: bool = True) -> "AgentConfigBuilder":
|
|
198
|
+
"""Temporarily disable the background Planner validation task.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
disable: Whether to disable the planner validation
|
|
202
|
+
"""
|
|
203
|
+
self._disable_planner_validation = disable
|
|
204
|
+
return self
|
|
205
|
+
|
|
206
|
+
def with_planner_validation(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
207
|
+
"""Configure the advisory async Planner validation on milestone changes.
|
|
208
|
+
|
|
209
|
+
Every top-level milestone text change is reviewed by the lightweight
|
|
210
|
+
validator; a flagged change only yields a hint plus reason for the
|
|
211
|
+
Operator (no rollback, no action suppression).
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
enabled: Whether planner validation is enabled
|
|
215
|
+
"""
|
|
216
|
+
self._disable_planner_validation = not enabled
|
|
217
|
+
return self
|
|
218
|
+
|
|
219
|
+
def with_enable_committee(self, enabled: bool = True) -> "AgentConfigBuilder":
|
|
220
|
+
"""Enable or disable the Committee council debate tool for Operator."""
|
|
221
|
+
self._enable_committee = enabled
|
|
222
|
+
return self
|
|
223
|
+
|
|
224
|
+
def with_committee(self, enabled: bool = True, debate_rounds: int = 2) -> "AgentConfigBuilder":
|
|
225
|
+
"""Configure Multi-Agent Committee council debate settings.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
enabled: Whether committee debate tool is enabled
|
|
229
|
+
debate_rounds: Number of debate rounds (1-5)
|
|
230
|
+
"""
|
|
231
|
+
self._enable_committee = enabled
|
|
232
|
+
self._committee_debate_rounds = debate_rounds
|
|
233
|
+
return self
|
|
234
|
+
|
|
235
|
+
def with_outputter(
|
|
236
|
+
self,
|
|
237
|
+
enabled: bool = True,
|
|
238
|
+
force_synthesis: bool = False,
|
|
239
|
+
) -> "AgentConfigBuilder":
|
|
240
|
+
"""Configure Outputter post-execution synthesis agent options.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
enabled: Whether Outputter is mounted to synthesize final outputs
|
|
244
|
+
force_synthesis: Force Outputter synthesis even if no structured output schema is specified
|
|
245
|
+
"""
|
|
246
|
+
self._outputter = self._outputter.model_copy(
|
|
247
|
+
update={"enabled": enabled, "force_synthesis": force_synthesis}
|
|
248
|
+
)
|
|
249
|
+
self._disable_outputter = not enabled
|
|
250
|
+
return self
|
|
251
|
+
|
|
252
|
+
def with_disable_outputter(self, disable: bool = True) -> "AgentConfigBuilder":
|
|
253
|
+
"""Disable Outputter agent execution."""
|
|
254
|
+
self._disable_outputter = disable
|
|
255
|
+
self._outputter = self._outputter.model_copy(update={"enabled": not disable})
|
|
256
|
+
return self
|
|
257
|
+
|
|
258
|
+
def with_flash_config(
|
|
259
|
+
self,
|
|
260
|
+
max_turns: int | None = None,
|
|
261
|
+
explorer_mode: ExplorerVersion | None = None,
|
|
262
|
+
step_summarizer: bool | None = None,
|
|
263
|
+
step_summarizer_model: str | None = None,
|
|
264
|
+
prune_history_xml: bool | None = None,
|
|
265
|
+
) -> "AgentConfigBuilder":
|
|
266
|
+
"""Configure ⚡ Flash execution profile options.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
max_turns: Maximum reactive loop turns (0 = unlimited)
|
|
270
|
+
explorer_mode: Explorer tier used by the Flash runner's ``ask_explorer``
|
|
271
|
+
('flash' one-shot detection, 'pro' short reasoning loop, 'ultra'
|
|
272
|
+
deep loop); mirrored to ``explorer.flash_mode``
|
|
273
|
+
step_summarizer: Enable/disable asynchronous visual context compressor
|
|
274
|
+
step_summarizer_model: Lightweight model for background step summarization
|
|
275
|
+
prune_history_xml: Whether to prune outdated XML trees from historical steps
|
|
276
|
+
"""
|
|
277
|
+
updates: dict[str, Any] = {}
|
|
278
|
+
if max_turns is not None:
|
|
279
|
+
updates["max_turns"] = max_turns
|
|
280
|
+
if explorer_mode is not None:
|
|
281
|
+
updates["explorer_mode"] = explorer_mode
|
|
282
|
+
self._explorer = self._explorer.model_copy(update={"flash_mode": explorer_mode})
|
|
283
|
+
if (
|
|
284
|
+
step_summarizer is not None
|
|
285
|
+
or step_summarizer_model is not None
|
|
286
|
+
or prune_history_xml is not None
|
|
287
|
+
):
|
|
288
|
+
sum_updates: dict[str, Any] = {}
|
|
289
|
+
if step_summarizer is not None:
|
|
290
|
+
sum_updates["enabled"] = step_summarizer
|
|
291
|
+
if step_summarizer_model is not None:
|
|
292
|
+
sum_updates["model"] = step_summarizer_model
|
|
293
|
+
if prune_history_xml is not None:
|
|
294
|
+
sum_updates["prune_history_xml"] = prune_history_xml
|
|
295
|
+
updates["step_summarizer"] = self._flash.step_summarizer.model_copy(update=sum_updates)
|
|
296
|
+
if updates:
|
|
297
|
+
self._flash = self._flash.model_copy(update=updates)
|
|
298
|
+
return self
|
|
299
|
+
|
|
300
|
+
def with_flash_step_summarizer(
|
|
301
|
+
self,
|
|
302
|
+
enabled: bool = True,
|
|
303
|
+
model: str | None = None,
|
|
304
|
+
prune_history_xml: bool | None = None,
|
|
305
|
+
) -> "AgentConfigBuilder":
|
|
306
|
+
"""Configure Flash asynchronous step state summarizer options."""
|
|
307
|
+
return self.with_flash_config(
|
|
308
|
+
step_summarizer=enabled,
|
|
309
|
+
step_summarizer_model=model,
|
|
310
|
+
prune_history_xml=prune_history_xml,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
def with_pro_config(
|
|
314
|
+
self,
|
|
315
|
+
explorer_mode: ExplorerVersion | None = None,
|
|
316
|
+
planner_validation: bool | None = None,
|
|
317
|
+
committee: bool | None = None,
|
|
318
|
+
checker: bool | None = None,
|
|
319
|
+
video_ledger: bool | None = None,
|
|
320
|
+
verification_level: str | None = None,
|
|
321
|
+
) -> "AgentConfigBuilder":
|
|
322
|
+
"""Configure 🚀 Pro execution profile options.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
explorer_mode: Explorer tier used by the Pro profile's Operator / Validator
|
|
326
|
+
('flash', 'pro', or 'ultra'); mirrored to ``explorer.pro_mode``
|
|
327
|
+
planner_validation: Enable/disable the advisory review of plan milestone edits
|
|
328
|
+
committee: Enable/disable multi-agent committee debate tool
|
|
329
|
+
checker: Enable/disable the Checker (plan checkpoint verification + exit final review)
|
|
330
|
+
video_ledger: Enable/disable screen video action ledger tracking
|
|
331
|
+
verification_level: Coarse Checker preset ('off', 'final', 'checkpoints',
|
|
332
|
+
'strict'); applied before the explicit ``checker`` switch so the
|
|
333
|
+
switch still wins when both are given
|
|
334
|
+
"""
|
|
335
|
+
if explorer_mode is not None:
|
|
336
|
+
self._pro = self._pro.model_copy(
|
|
337
|
+
update={"explorer": self._pro.explorer.model_copy(update={"mode": explorer_mode})}
|
|
338
|
+
)
|
|
339
|
+
self._explorer = self._explorer.model_copy(update={"pro_mode": explorer_mode})
|
|
340
|
+
if planner_validation is not None:
|
|
341
|
+
self.with_planner_validation(enabled=planner_validation)
|
|
342
|
+
if committee is not None:
|
|
343
|
+
self.with_committee(enabled=committee)
|
|
344
|
+
if verification_level is not None:
|
|
345
|
+
self.with_verification_level(verification_level)
|
|
346
|
+
if checker is not None:
|
|
347
|
+
self.with_checker(enabled=checker)
|
|
348
|
+
if video_ledger is not None:
|
|
349
|
+
self._enable_video_ledger = video_ledger
|
|
350
|
+
self._pro = self._pro.model_copy(
|
|
351
|
+
update={
|
|
352
|
+
"video_analyzer": self._pro.video_analyzer.model_copy(
|
|
353
|
+
update={"enable_ledger": video_ledger}
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
return self
|
|
358
|
+
|
|
359
|
+
def with_explorer(
|
|
360
|
+
self,
|
|
361
|
+
version: ExplorerVersion | None = None,
|
|
362
|
+
default_version: ExplorerVersion | None = None,
|
|
363
|
+
flash_mode: ExplorerVersion | None = None,
|
|
364
|
+
pro_mode: ExplorerVersion | None = None,
|
|
365
|
+
caching: bool | None = None,
|
|
366
|
+
versions: dict[str, ExplorerVersion] | None = None,
|
|
367
|
+
) -> "AgentConfigBuilder":
|
|
368
|
+
"""Configure the Explorer tier behind ``ask_explorer``.
|
|
369
|
+
|
|
370
|
+
The tier is a user setting resolved per execution profile; calling agents
|
|
371
|
+
never see it. Precedence at run time: ``ARTEMIS_EXPLORER_VERSION``, then
|
|
372
|
+
``versions`` (per-agent override), then the profile knob (``flash_mode``
|
|
373
|
+
for the Flash runner, ``pro_mode`` for the Pro Operator / Validator), then
|
|
374
|
+
``default_version``.
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
version: Fallback tier when no profile knob applies ('flash', 'pro', 'ultra')
|
|
378
|
+
default_version: Alias for version
|
|
379
|
+
flash_mode: Tier for the Flash execution profile (FlashRunner)
|
|
380
|
+
pro_mode: Tier for the Pro execution profile (Operator / Validator)
|
|
381
|
+
caching: Gemini explicit context caching for the multi-turn tiers;
|
|
382
|
+
None keeps the per-tier default (off for pro, on for ultra)
|
|
383
|
+
versions: Advanced per-agent override, e.g. ``{"validator": "ultra"}``;
|
|
384
|
+
empty by default so the profile knobs decide
|
|
385
|
+
"""
|
|
386
|
+
target_version = version if version is not None else default_version
|
|
387
|
+
updates = {}
|
|
388
|
+
if target_version is not None:
|
|
389
|
+
updates["default_version"] = target_version
|
|
390
|
+
if flash_mode is not None:
|
|
391
|
+
updates["flash_mode"] = flash_mode
|
|
392
|
+
if pro_mode is not None:
|
|
393
|
+
updates["pro_mode"] = pro_mode
|
|
394
|
+
if caching is not None:
|
|
395
|
+
updates["caching"] = caching
|
|
396
|
+
if updates:
|
|
397
|
+
self._explorer = self._explorer.model_copy(update=updates)
|
|
398
|
+
if versions is not None:
|
|
399
|
+
self._explorer_versions = versions
|
|
400
|
+
return self
|
|
401
|
+
|
|
402
|
+
def with_explorer_version(self, version: ExplorerVersion) -> "AgentConfigBuilder":
|
|
403
|
+
"""Configure the fallback Explorer tier ('flash', 'pro', or 'ultra').
|
|
404
|
+
|
|
405
|
+
Only applies when no profile knob matches; prefer :meth:`with_flash_config`
|
|
406
|
+
/ :meth:`with_pro_config` (or :meth:`with_explorer`) for the per-profile tiers.
|
|
407
|
+
"""
|
|
408
|
+
self._explorer = self._explorer.model_copy(update={"default_version": version})
|
|
409
|
+
return self
|
|
410
|
+
|
|
411
|
+
def with_explorer_versions(self, versions: dict[str, ExplorerVersion]) -> "AgentConfigBuilder":
|
|
412
|
+
"""Configure the advanced per-agent Explorer tier override (empty by default)."""
|
|
413
|
+
self._explorer_versions = versions
|
|
414
|
+
return self
|
|
415
|
+
|
|
416
|
+
def with_denylisted_tools(self, tools: dict[str, list[str]]) -> "AgentConfigBuilder":
|
|
417
|
+
"""Configure denylisted tools."""
|
|
418
|
+
self._denylisted_tools = tools
|
|
419
|
+
return self
|
|
420
|
+
|
|
421
|
+
def _extra_config_fields(self) -> dict[str, Any]:
|
|
422
|
+
return {
|
|
423
|
+
"device_id": (
|
|
424
|
+
self._device_id
|
|
425
|
+
or os.environ.get("ARTEMIS_DEVICE_ID")
|
|
426
|
+
or os.environ.get("ADB_DEVICE_SERIAL")
|
|
427
|
+
),
|
|
428
|
+
"video_recording_tools_enabled": self._video_recording_tools_enabled,
|
|
429
|
+
"force_web_accessibility": self._force_web_accessibility,
|
|
430
|
+
"disable_checker": self._disable_checker,
|
|
431
|
+
"disable_midway_checks": self._disable_midway_checks,
|
|
432
|
+
"disable_final_check": self._disable_final_check,
|
|
433
|
+
"checker_max_iterations": self._checker_max_iterations,
|
|
434
|
+
"final_check_max_attempts": self._final_check_max_attempts,
|
|
435
|
+
"checkpoint_max_repairs": self._checkpoint_max_repairs,
|
|
436
|
+
"max_concurrent_checkpoints": self._max_concurrent_checkpoints,
|
|
437
|
+
"checkpoint_timeout": self._checkpoint_timeout,
|
|
438
|
+
"settlement_timeout": self._settlement_timeout,
|
|
439
|
+
"assert_failure_policy": self._assert_failure_policy,
|
|
440
|
+
"disable_device_probes": self._disable_device_probes,
|
|
441
|
+
"disable_planner_validation": self._disable_planner_validation,
|
|
442
|
+
"enable_committee": self._enable_committee,
|
|
443
|
+
"committee_debate_rounds": self._committee_debate_rounds,
|
|
444
|
+
"disable_outputter": self._disable_outputter,
|
|
445
|
+
"outputter": self._outputter,
|
|
446
|
+
"flash": self._flash,
|
|
447
|
+
"pro": self._pro,
|
|
448
|
+
"explorer": self._explorer,
|
|
449
|
+
"explorer_versions": self._explorer_versions,
|
|
450
|
+
"denylisted_tools": self._denylisted_tools,
|
|
451
|
+
"enable_video_ledger": self._enable_video_ledger,
|
|
452
|
+
"video_analyzer": self._video_analyzer.model_copy(
|
|
453
|
+
update={"enable_ledger": self._enable_video_ledger}
|
|
454
|
+
),
|
|
455
|
+
"concurrency_mode": self._concurrency_mode,
|
|
456
|
+
"max_concurrency": self._max_concurrency,
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
def build(self, validate_profiles: bool = True) -> AgentConfig:
|
|
460
|
+
return cast(AgentConfig, super().build(validate_profiles=validate_profiles))
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def get_default_servers():
|
|
464
|
+
|
|
465
|
+
host = settings.ADB_HOST or os.environ.get("ADB_HOST", "localhost")
|
|
466
|
+
port_val = settings.ADB_PORT
|
|
467
|
+
if not port_val:
|
|
468
|
+
port_str = os.environ.get("ADB_PORT", "5037")
|
|
469
|
+
port_val = int(port_str) if port_str.isdigit() else 5037
|
|
470
|
+
|
|
471
|
+
return ServerConfig(
|
|
472
|
+
adb_host=host,
|
|
473
|
+
adb_port=port_val,
|
|
474
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
DEFAULT_PROFILE_NAME = "default"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Run outcome helpers: test summary attachment and trace naming."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def attach_test_summary(output, run_outcome: dict | None):
|
|
19
|
+
"""Surfaces the machine-readable test summary in the task's return value.
|
|
20
|
+
|
|
21
|
+
Only applies when the run actually had check items (the summary carries at
|
|
22
|
+
least one counted item) — otherwise the historical return shape is kept
|
|
23
|
+
untouched. String outputs are wrapped into a dict so that callers such as
|
|
24
|
+
``mobile_run_task`` receive the summary without parsing report prose.
|
|
25
|
+
"""
|
|
26
|
+
if not run_outcome:
|
|
27
|
+
return output
|
|
28
|
+
tests = run_outcome.get("tests") or {}
|
|
29
|
+
total = (
|
|
30
|
+
int(tests.get("passed", 0))
|
|
31
|
+
+ int(tests.get("failed", 0))
|
|
32
|
+
+ int(tests.get("inconclusive", 0))
|
|
33
|
+
+ int(tests.get("unchecked", 0))
|
|
34
|
+
)
|
|
35
|
+
if total <= 0:
|
|
36
|
+
return output
|
|
37
|
+
summary = {"task_status": run_outcome.get("task_status"), **tests}
|
|
38
|
+
if isinstance(output, dict):
|
|
39
|
+
merged = dict(output)
|
|
40
|
+
merged.setdefault("test_summary", summary)
|
|
41
|
+
return merged
|
|
42
|
+
if output is None:
|
|
43
|
+
return {"test_summary": summary}
|
|
44
|
+
if isinstance(output, str):
|
|
45
|
+
return {"result": output, "test_summary": summary}
|
|
46
|
+
# Typed/structured outputs keep their shape; the summary stays available in
|
|
47
|
+
# run_outcome.json and the session state.
|
|
48
|
+
return output
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def resolve_trace_suffix(task_status: str, run_outcome: dict | None) -> str:
|
|
52
|
+
"""Trace naming: assertion failures must be distinguishable from _PASS."""
|
|
53
|
+
if task_status != "completed":
|
|
54
|
+
return "_FAIL"
|
|
55
|
+
tests = (run_outcome or {}).get("tests") or {}
|
|
56
|
+
if int(tests.get("failed", 0)) > 0:
|
|
57
|
+
return "_TESTFAIL"
|
|
58
|
+
return "_PASS"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Type definitions for the ARTEMIS SDK."""
|
|
16
|
+
|
|
17
|
+
from artemis.context import DevicePlatform
|
|
18
|
+
from artemis.sdk.types.agent import (
|
|
19
|
+
AgentConfig,
|
|
20
|
+
ApiBaseUrl,
|
|
21
|
+
ServerConfig,
|
|
22
|
+
)
|
|
23
|
+
from third_party.mobile_use.sdk.types.exceptions import (
|
|
24
|
+
AgentError,
|
|
25
|
+
AgentNotInitializedError,
|
|
26
|
+
AgentProfileNotFoundError,
|
|
27
|
+
AgentTaskRequestError,
|
|
28
|
+
DeviceError,
|
|
29
|
+
DeviceNotFoundError,
|
|
30
|
+
ArtemisError,
|
|
31
|
+
ServerError,
|
|
32
|
+
ServerStartupError,
|
|
33
|
+
)
|
|
34
|
+
from third_party.mobile_use.sdk.types.task import (
|
|
35
|
+
AgentProfile,
|
|
36
|
+
Task,
|
|
37
|
+
TaskRequest,
|
|
38
|
+
TaskRequestCommon,
|
|
39
|
+
TaskResult,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
"ApiBaseUrl",
|
|
44
|
+
"AgentConfig",
|
|
45
|
+
"DevicePlatform",
|
|
46
|
+
"AgentProfile",
|
|
47
|
+
"ServerConfig",
|
|
48
|
+
"TaskRequest",
|
|
49
|
+
"TaskResult",
|
|
50
|
+
"TaskRequestCommon",
|
|
51
|
+
"Task",
|
|
52
|
+
"AgentProfileNotFoundError",
|
|
53
|
+
"AgentTaskRequestError",
|
|
54
|
+
"DeviceNotFoundError",
|
|
55
|
+
"ServerStartupError",
|
|
56
|
+
"AgentError",
|
|
57
|
+
"AgentNotInitializedError",
|
|
58
|
+
"DeviceError",
|
|
59
|
+
"ArtemisError",
|
|
60
|
+
"ServerError",
|
|
61
|
+
]
|