android-midscene-automation 0.2.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +159 -29
  3. package/artemis-main/.dockerignore +15 -0
  4. package/artemis-main/.env.example +34 -0
  5. package/artemis-main/CONTRIBUTING.md +35 -0
  6. package/artemis-main/Dockerfile +68 -0
  7. package/artemis-main/LICENSE +202 -0
  8. package/artemis-main/Makefile +115 -0
  9. package/artemis-main/README.md +322 -0
  10. package/artemis-main/README_CN.md +320 -0
  11. package/artemis-main/apps/__init__.py +15 -0
  12. package/artemis-main/apps/admin_console/__init__.py +19 -0
  13. package/artemis-main/apps/admin_console/core/__init__.py +13 -0
  14. package/artemis-main/apps/admin_console/core/config.py +43 -0
  15. package/artemis-main/apps/admin_console/core/security.py +178 -0
  16. package/artemis-main/apps/admin_console/core/state.py +243 -0
  17. package/artemis-main/apps/admin_console/database/__init__.py +13 -0
  18. package/artemis-main/apps/admin_console/database/connection.py +60 -0
  19. package/artemis-main/apps/admin_console/database/repositories/__init__.py +13 -0
  20. package/artemis-main/apps/admin_console/database/repositories/session_repository.py +564 -0
  21. package/artemis-main/apps/admin_console/database/repositories/step_repository.py +512 -0
  22. package/artemis-main/apps/admin_console/database/repositories/trace_repository.py +133 -0
  23. package/artemis-main/apps/admin_console/index.html +3787 -0
  24. package/artemis-main/apps/admin_console/replay_manager.py +2585 -0
  25. package/artemis-main/apps/admin_console/routers/__init__.py +13 -0
  26. package/artemis-main/apps/admin_console/routers/media.py +198 -0
  27. package/artemis-main/apps/admin_console/routers/replay.py +91 -0
  28. package/artemis-main/apps/admin_console/routers/sessions.py +239 -0
  29. package/artemis-main/apps/admin_console/routers/steps.py +109 -0
  30. package/artemis-main/apps/admin_console/routers/stream.py +56 -0
  31. package/artemis-main/apps/admin_console/routers/system.py +761 -0
  32. package/artemis-main/apps/admin_console/routers/tasks.py +517 -0
  33. package/artemis-main/apps/admin_console/schemas/__init__.py +13 -0
  34. package/artemis-main/apps/admin_console/schemas/task_schema.py +47 -0
  35. package/artemis-main/apps/admin_console/server.py +508 -0
  36. package/artemis-main/apps/admin_console/services/__init__.py +13 -0
  37. package/artemis-main/apps/admin_console/services/device_stream_service.py +137 -0
  38. package/artemis-main/apps/admin_console/services/ipc_service.py +262 -0
  39. package/artemis-main/apps/admin_console/services/media_service.py +623 -0
  40. package/artemis-main/apps/admin_console/services/model_service.py +148 -0
  41. package/artemis-main/apps/admin_console/services/task_preset_catalog.py +514 -0
  42. package/artemis-main/apps/admin_console/services/task_queue_service.py +1719 -0
  43. package/artemis-main/apps/admin_console/services/worker_process_io.py +144 -0
  44. package/artemis-main/apps/showcase_ui/README.md +31 -0
  45. package/artemis-main/apps/showcase_ui/angular.json +132 -0
  46. package/artemis-main/apps/showcase_ui/package-lock.json +9472 -0
  47. package/artemis-main/apps/showcase_ui/package.json +39 -0
  48. package/artemis-main/apps/showcase_ui/proxy.conf.json +23 -0
  49. package/artemis-main/apps/showcase_ui/public/favicon.ico +0 -0
  50. package/artemis-main/apps/showcase_ui/public/logo.png +0 -0
  51. package/artemis-main/apps/showcase_ui/public/logo.svg +56 -0
  52. package/artemis-main/apps/showcase_ui/src/app/app.component.html +24 -0
  53. package/artemis-main/apps/showcase_ui/src/app/app.component.scss +49 -0
  54. package/artemis-main/apps/showcase_ui/src/app/app.component.spec.ts +42 -0
  55. package/artemis-main/apps/showcase_ui/src/app/app.component.ts +32 -0
  56. package/artemis-main/apps/showcase_ui/src/app/app.config.ts +29 -0
  57. package/artemis-main/apps/showcase_ui/src/app/app.routes.ts +27 -0
  58. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream-startup.spec.ts +108 -0
  59. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.html +1436 -0
  60. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.scss +3973 -0
  61. package/artemis-main/apps/showcase_ui/src/app/components/agent-stream/agent-stream.component.ts +2235 -0
  62. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.html +380 -0
  63. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.scss +1171 -0
  64. package/artemis-main/apps/showcase_ui/src/app/components/chat-interface/chat-interface.component.ts +270 -0
  65. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.html +433 -0
  66. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.scss +987 -0
  67. package/artemis-main/apps/showcase_ui/src/app/components/floating-video-player/floating-video-player.component.ts +632 -0
  68. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.html +130 -0
  69. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.scss +406 -0
  70. package/artemis-main/apps/showcase_ui/src/app/components/legacy-agent-stream/legacy-agent-stream.component.ts +74 -0
  71. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.scss +115 -0
  72. package/artemis-main/apps/showcase_ui/src/app/components/nav-switcher/nav-switcher.component.ts +52 -0
  73. package/artemis-main/apps/showcase_ui/src/app/core/data/smart-tasks.data.ts +334 -0
  74. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.spec.ts +55 -0
  75. package/artemis-main/apps/showcase_ui/src/app/core/i18n/language.service.ts +61 -0
  76. package/artemis-main/apps/showcase_ui/src/app/core/i18n/translate.pipe.ts +11 -0
  77. package/artemis-main/apps/showcase_ui/src/app/core/i18n/zh-cn.ts +651 -0
  78. package/artemis-main/apps/showcase_ui/src/app/core/models/markdown.model.ts +43 -0
  79. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.spec.ts +47 -0
  80. package/artemis-main/apps/showcase_ui/src/app/core/models/pro-tuning.model.ts +165 -0
  81. package/artemis-main/apps/showcase_ui/src/app/core/models/session.model.ts +85 -0
  82. package/artemis-main/apps/showcase_ui/src/app/core/models/stream.model.ts +246 -0
  83. package/artemis-main/apps/showcase_ui/src/app/core/models/system.model.ts +118 -0
  84. package/artemis-main/apps/showcase_ui/src/app/core/services/task-recommendation.service.ts +111 -0
  85. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.html +2130 -0
  86. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.scss +5204 -0
  87. package/artemis-main/apps/showcase_ui/src/app/pages/home/home.component.ts +1189 -0
  88. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.html +39 -0
  89. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.scss +151 -0
  90. package/artemis-main/apps/showcase_ui/src/app/pages/legacy-workspace/legacy-workspace.component.ts +58 -0
  91. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.html +201 -0
  92. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.scss +886 -0
  93. package/artemis-main/apps/showcase_ui/src/app/pages/workspace/workspace.component.ts +324 -0
  94. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.spec.ts +418 -0
  95. package/artemis-main/apps/showcase_ui/src/app/services/agent.service.ts +2012 -0
  96. package/artemis-main/apps/showcase_ui/src/app/services/system.service.spec.ts +173 -0
  97. package/artemis-main/apps/showcase_ui/src/app/services/system.service.ts +620 -0
  98. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.spec.ts +513 -0
  99. package/artemis-main/apps/showcase_ui/src/app/utils/action-formatter.util.ts +1015 -0
  100. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.spec.ts +85 -0
  101. package/artemis-main/apps/showcase_ui/src/app/utils/image-overlay.util.ts +662 -0
  102. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts +70 -0
  103. package/artemis-main/apps/showcase_ui/src/app/utils/markdown-parser.util.ts +383 -0
  104. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.spec.ts +107 -0
  105. package/artemis-main/apps/showcase_ui/src/app/utils/recording-timeline.util.ts +123 -0
  106. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.spec.ts +92 -0
  107. package/artemis-main/apps/showcase_ui/src/app/utils/run-info.util.ts +116 -0
  108. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.spec.ts +640 -0
  109. package/artemis-main/apps/showcase_ui/src/app/utils/stream-aggregator.util.ts +1021 -0
  110. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.spec.ts +375 -0
  111. package/artemis-main/apps/showcase_ui/src/app/utils/tool-formatter.util.ts +1419 -0
  112. package/artemis-main/apps/showcase_ui/src/index.html +37 -0
  113. package/artemis-main/apps/showcase_ui/src/main.ts +22 -0
  114. package/artemis-main/apps/showcase_ui/src/styles.scss +60 -0
  115. package/artemis-main/apps/showcase_ui/tsconfig.app.json +23 -0
  116. package/artemis-main/apps/showcase_ui/tsconfig.json +27 -0
  117. package/artemis-main/apps/showcase_ui/tsconfig.spec.json +23 -0
  118. package/artemis-main/artemis/__init__.py +44 -0
  119. package/artemis-main/artemis/__main__.py +18 -0
  120. package/artemis-main/artemis/_legacy_imports.py +94 -0
  121. package/artemis-main/artemis/_version.py +30 -0
  122. package/artemis-main/artemis/agents/__init__.py +17 -0
  123. package/artemis-main/artemis/agents/checker/checker.json +9 -0
  124. package/artemis-main/artemis/agents/checker/checker.py +859 -0
  125. package/artemis-main/artemis/agents/diagnoser/diagnoser.json +23 -0
  126. package/artemis-main/artemis/agents/diagnoser/diagnoser.py +608 -0
  127. package/artemis-main/artemis/agents/explorer/constants.py +52 -0
  128. package/artemis-main/artemis/agents/explorer/explorer.json +57 -0
  129. package/artemis-main/artemis/agents/explorer/explorer.py +473 -0
  130. package/artemis-main/artemis/agents/explorer/geometry.py +73 -0
  131. package/artemis-main/artemis/agents/explorer/native_runner.py +878 -0
  132. package/artemis-main/artemis/agents/explorer/perception_tools.py +632 -0
  133. package/artemis-main/artemis/agents/explorer/run_setup.py +403 -0
  134. package/artemis-main/artemis/agents/explorer/screen_index.py +266 -0
  135. package/artemis-main/artemis/agents/explorer/tiers.py +110 -0
  136. package/artemis-main/artemis/agents/explorer/tool_declarations.py +394 -0
  137. package/artemis-main/artemis/agents/explorer/universal_runner.py +317 -0
  138. package/artemis-main/artemis/agents/flash/context_compressor.py +452 -0
  139. package/artemis-main/artemis/agents/flash/flash_runner.md +51 -0
  140. package/artemis-main/artemis/agents/flash/flash_summarizer.md +53 -0
  141. package/artemis-main/artemis/agents/flash/flash_summarizer_single.md +54 -0
  142. package/artemis-main/artemis/agents/flash/runner.py +1167 -0
  143. package/artemis-main/artemis/agents/flash/summarizer.py +511 -0
  144. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.md +8 -0
  145. package/artemis-main/artemis/agents/history_analyzer/history_analyzer.py +182 -0
  146. package/artemis-main/artemis/agents/image_processor/image_processor.md +74 -0
  147. package/artemis-main/artemis/agents/image_processor/image_processor.py +322 -0
  148. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.md +15 -0
  149. package/artemis-main/artemis/agents/log_analyzer/log_analyzer.py +403 -0
  150. package/artemis-main/artemis/agents/log_analyzer/log_reader_sub_agent.md +8 -0
  151. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.md +11 -0
  152. package/artemis-main/artemis/agents/log_analyzer/output_analyzer.py +163 -0
  153. package/artemis-main/artemis/agents/object_detector/object_detector.json +9 -0
  154. package/artemis-main/artemis/agents/object_detector/object_detector.py +211 -0
  155. package/artemis-main/artemis/agents/operator/operator.json +3 -0
  156. package/artemis-main/artemis/agents/operator/operator.py +1394 -0
  157. package/artemis-main/artemis/agents/operator/prompts.py +1064 -0
  158. package/artemis-main/artemis/agents/outputter/outputter.md +36 -0
  159. package/artemis-main/artemis/agents/outputter/outputter.py +552 -0
  160. package/artemis-main/artemis/agents/planner/planner.json +32 -0
  161. package/artemis-main/artemis/agents/planner/planner.py +436 -0
  162. package/artemis-main/artemis/agents/prompt_assembly.py +79 -0
  163. package/artemis-main/artemis/agents/summarizer/summarizer.py +190 -0
  164. package/artemis-main/artemis/agents/validator/action_execution.py +98 -0
  165. package/artemis-main/artemis/agents/validator/categories.py +33 -0
  166. package/artemis-main/artemis/agents/validator/execution_loop.py +488 -0
  167. package/artemis-main/artemis/agents/validator/incidents.py +120 -0
  168. package/artemis-main/artemis/agents/validator/pixel_safety_net.md +15 -0
  169. package/artemis-main/artemis/agents/validator/precondition_pixel.py +320 -0
  170. package/artemis-main/artemis/agents/validator/precondition_xml.py +672 -0
  171. package/artemis-main/artemis/agents/validator/tool_declarations.py +332 -0
  172. package/artemis-main/artemis/agents/validator/validator.py +188 -0
  173. package/artemis-main/artemis/agents/video_analyzer/__init__.py +15 -0
  174. package/artemis-main/artemis/agents/video_analyzer/audio_native.py +543 -0
  175. package/artemis-main/artemis/agents/video_analyzer/blackboard.py +821 -0
  176. package/artemis-main/artemis/agents/video_analyzer/chunk_agentic.py +455 -0
  177. package/artemis-main/artemis/agents/video_analyzer/chunk_conversation.py +491 -0
  178. package/artemis-main/artemis/agents/video_analyzer/chunk_native.py +437 -0
  179. package/artemis-main/artemis/agents/video_analyzer/conflict_resolution.py +137 -0
  180. package/artemis-main/artemis/agents/video_analyzer/gemini_files.py +162 -0
  181. package/artemis-main/artemis/agents/video_analyzer/native_coordinator.py +541 -0
  182. package/artemis-main/artemis/agents/video_analyzer/reliability.py +128 -0
  183. package/artemis-main/artemis/agents/video_analyzer/universal_engine.py +487 -0
  184. package/artemis-main/artemis/agents/video_analyzer/universal_tools.py +323 -0
  185. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.md +51 -0
  186. package/artemis-main/artemis/agents/video_analyzer/video_analyzer.py +875 -0
  187. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent.md +15 -0
  188. package/artemis-main/artemis/agents/video_analyzer/video_sub_agent_audio.md +12 -0
  189. package/artemis-main/artemis/clients/accessibility_client.py +438 -0
  190. package/artemis-main/artemis/clients/screen_client_factory.py +403 -0
  191. package/artemis-main/artemis/config/__init__.py +309 -0
  192. package/artemis-main/artemis/config/agent.py +1098 -0
  193. package/artemis-main/artemis/config/constants.py +151 -0
  194. package/artemis-main/artemis/config/core/__init__.py +24 -0
  195. package/artemis-main/artemis/config/core/engine.py +118 -0
  196. package/artemis-main/artemis/config/core/interpolator.py +78 -0
  197. package/artemis-main/artemis/config/llm.py +267 -0
  198. package/artemis-main/artemis/config/paths.py +244 -0
  199. package/artemis-main/artemis/config/runtime.py +197 -0
  200. package/artemis-main/artemis/config/settings.py +315 -0
  201. package/artemis-main/artemis/constants.py +47 -0
  202. package/artemis-main/artemis/context.py +289 -0
  203. package/artemis-main/artemis/controllers/__init__.py +41 -0
  204. package/artemis-main/artemis/controllers/controller_factory.py +41 -0
  205. package/artemis-main/artemis/controllers/device_controller.py +29 -0
  206. package/artemis-main/artemis/controllers/types.py +37 -0
  207. package/artemis-main/artemis/controllers/unified_controller.py +649 -0
  208. package/artemis-main/artemis/core/__init__.py +21 -0
  209. package/artemis-main/artemis/core/diagnostics/__init__.py +90 -0
  210. package/artemis-main/artemis/core/diagnostics/adb_keys.py +270 -0
  211. package/artemis-main/artemis/core/diagnostics/adb_server_connection.py +330 -0
  212. package/artemis-main/artemis/core/diagnostics/device_smoke.py +364 -0
  213. package/artemis-main/artemis/core/diagnostics/emulator_manager.py +501 -0
  214. package/artemis-main/artemis/core/diagnostics/engine.py +438 -0
  215. package/artemis-main/artemis/core/diagnostics/hierarchy_parity.py +216 -0
  216. package/artemis-main/artemis/core/diagnostics/probes/adb_probe.py +887 -0
  217. package/artemis-main/artemis/core/diagnostics/probes/base.py +45 -0
  218. package/artemis-main/artemis/core/diagnostics/probes/credentials_probe.py +296 -0
  219. package/artemis-main/artemis/core/diagnostics/probes/host_probe.py +427 -0
  220. package/artemis-main/artemis/core/diagnostics/probes/runtime_probe.py +169 -0
  221. package/artemis-main/artemis/core/diagnostics/probes/toolchain_probe.py +139 -0
  222. package/artemis-main/artemis/core/diagnostics/readiness.py +83 -0
  223. package/artemis-main/artemis/core/diagnostics/schema.py +118 -0
  224. package/artemis-main/artemis/core/tool_declaration.py +43 -0
  225. package/artemis-main/artemis/core/tool_failure.py +56 -0
  226. package/artemis-main/artemis/data_engine/context_vars.py +24 -0
  227. package/artemis-main/artemis/data_engine/engine.py +1615 -0
  228. package/artemis-main/artemis/data_engine/history_reader.py +142 -0
  229. package/artemis-main/artemis/data_engine/models.py +131 -0
  230. package/artemis-main/artemis/data_engine/storage.py +1245 -0
  231. package/artemis-main/artemis/data_engine/trace.py +727 -0
  232. package/artemis-main/artemis/drivers/__init__.py +48 -0
  233. package/artemis-main/artemis/drivers/android/adb_driver.py +507 -0
  234. package/artemis-main/artemis/drivers/android/hierarchy.py +64 -0
  235. package/artemis-main/artemis/drivers/android/input_ime.py +120 -0
  236. package/artemis-main/artemis/drivers/android/recorder.py +57 -0
  237. package/artemis-main/artemis/drivers/base.py +290 -0
  238. package/artemis-main/artemis/drivers/cloud/cloud_driver.py +117 -0
  239. package/artemis-main/artemis/drivers/factory.py +80 -0
  240. package/artemis-main/artemis/drivers/mock/mock_driver.py +198 -0
  241. package/artemis-main/artemis/drivers/types.py +67 -0
  242. package/artemis-main/artemis/graph/checkpoints.py +1243 -0
  243. package/artemis-main/artemis/graph/graph.py +1055 -0
  244. package/artemis-main/artemis/graph/perception.py +234 -0
  245. package/artemis-main/artemis/graph/state.py +151 -0
  246. package/artemis-main/artemis/graph/visibility.py +238 -0
  247. package/artemis-main/artemis/interfaces/cli/__init__.py +19 -0
  248. package/artemis-main/artemis/interfaces/cli/commands/__init__.py +15 -0
  249. package/artemis-main/artemis/interfaces/cli/commands/batch.py +278 -0
  250. package/artemis-main/artemis/interfaces/cli/commands/doctor.py +468 -0
  251. package/artemis-main/artemis/interfaces/cli/commands/helper.py +226 -0
  252. package/artemis-main/artemis/interfaces/cli/commands/init.py +193 -0
  253. package/artemis-main/artemis/interfaces/cli/commands/mcp.py +862 -0
  254. package/artemis-main/artemis/interfaces/cli/commands/run.py +463 -0
  255. package/artemis-main/artemis/interfaces/cli/commands/server.py +151 -0
  256. package/artemis-main/artemis/interfaces/cli/commands/server_lifecycle.py +328 -0
  257. package/artemis-main/artemis/interfaces/cli/commands/trace.py +111 -0
  258. package/artemis-main/artemis/interfaces/cli/commands/ui.py +404 -0
  259. package/artemis-main/artemis/interfaces/cli/main.py +109 -0
  260. package/artemis-main/artemis/interfaces/sdk/__init__.py +31 -0
  261. package/artemis-main/artemis/interfaces/sdk/client.py +19 -0
  262. package/artemis-main/artemis/interfaces/sdk/task.py +72 -0
  263. package/artemis-main/artemis/llm/__init__.py +25 -0
  264. package/artemis-main/artemis/llm/fake_model.py +179 -0
  265. package/artemis-main/artemis/llm/google/__init__.py +57 -0
  266. package/artemis-main/artemis/llm/google/provider.py +185 -0
  267. package/artemis-main/artemis/llm/google/usage.py +148 -0
  268. package/artemis-main/artemis/llm/parser.py +32 -0
  269. package/artemis-main/artemis/llm/reliability.py +267 -0
  270. package/artemis-main/artemis/llm/router.py +389 -0
  271. package/artemis-main/artemis/llm/schemas.py +36 -0
  272. package/artemis-main/artemis/llm/structured.py +196 -0
  273. package/artemis-main/artemis/main.py +58 -0
  274. package/artemis-main/artemis/mcp/__init__.py +20 -0
  275. package/artemis-main/artemis/mcp/action_executor.py +760 -0
  276. package/artemis-main/artemis/mcp/action_manifest.py +320 -0
  277. package/artemis-main/artemis/mcp/action_names.py +172 -0
  278. package/artemis-main/artemis/mcp/action_server.py +202 -0
  279. package/artemis-main/artemis/mcp/action_session.py +245 -0
  280. package/artemis-main/artemis/mcp/action_specs.py +868 -0
  281. package/artemis-main/artemis/mcp/action_types.py +86 -0
  282. package/artemis-main/artemis/mcp/actuators/__init__.py +21 -0
  283. package/artemis-main/artemis/mcp/actuators/adb.py +414 -0
  284. package/artemis-main/artemis/mcp/actuators/base.py +113 -0
  285. package/artemis-main/artemis/mcp/actuators/mock.py +70 -0
  286. package/artemis-main/artemis/mcp/adb_server.py +490 -0
  287. package/artemis-main/artemis/mcp/observation.py +133 -0
  288. package/artemis-main/artemis/mcp/xml_search_server.py +297 -0
  289. package/artemis-main/artemis/memory/__init__.py +90 -0
  290. package/artemis-main/artemis/memory/chunking.py +1843 -0
  291. package/artemis-main/artemis/memory/context_policy.py +226 -0
  292. package/artemis-main/artemis/memory/step_capsule.md +73 -0
  293. package/artemis-main/artemis/memory/step_memory.py +281 -0
  294. package/artemis-main/artemis/memory/transcript.py +798 -0
  295. package/artemis-main/artemis/platform/__init__.py +61 -0
  296. package/artemis-main/artemis/platform/base.py +104 -0
  297. package/artemis-main/artemis/platform/darwin.py +184 -0
  298. package/artemis-main/artemis/platform/linux.py +207 -0
  299. package/artemis-main/artemis/platform/windows.py +193 -0
  300. package/artemis-main/artemis/resources/__init__.py +46 -0
  301. package/artemis-main/artemis/runtime/__init__.py +108 -0
  302. package/artemis-main/artemis/runtime/adb_endpoint.py +173 -0
  303. package/artemis-main/artemis/runtime/awake_lease.py +283 -0
  304. package/artemis-main/artemis/runtime/awake_service.py +343 -0
  305. package/artemis-main/artemis/runtime/cancel_requests.py +254 -0
  306. package/artemis-main/artemis/runtime/daemon_client.py +422 -0
  307. package/artemis-main/artemis/runtime/device_lock.py +1013 -0
  308. package/artemis-main/artemis/runtime/device_pool.py +478 -0
  309. package/artemis-main/artemis/runtime/helper_manager.py +1030 -0
  310. package/artemis-main/artemis/runtime/process_probe.py +98 -0
  311. package/artemis-main/artemis/runtime/server_lifecycle.py +435 -0
  312. package/artemis-main/artemis/runtime/supervisor.py +121 -0
  313. package/artemis-main/artemis/runtime/trace_store.py +375 -0
  314. package/artemis-main/artemis/sdk/__init__.py +26 -0
  315. package/artemis-main/artemis/sdk/agent.py +485 -0
  316. package/artemis-main/artemis/sdk/builders/__init__.py +29 -0
  317. package/artemis-main/artemis/sdk/builders/agent_config_builder.py +474 -0
  318. package/artemis-main/artemis/sdk/constants.py +15 -0
  319. package/artemis-main/artemis/sdk/run_outcome.py +58 -0
  320. package/artemis-main/artemis/sdk/types/__init__.py +61 -0
  321. package/artemis-main/artemis/sdk/types/agent.py +89 -0
  322. package/artemis-main/artemis/sdk/utils.py +28 -0
  323. package/artemis-main/artemis/services/llm.py +1040 -0
  324. package/artemis-main/artemis/services/token_meter.py +267 -0
  325. package/artemis-main/artemis/telemetry/__init__.py +35 -0
  326. package/artemis-main/artemis/telemetry/models.py +64 -0
  327. package/artemis-main/artemis/telemetry/replay.py +34 -0
  328. package/artemis-main/artemis/telemetry/storage/json_storage.py +47 -0
  329. package/artemis-main/artemis/telemetry/tracer.py +85 -0
  330. package/artemis-main/artemis/toolchain/__init__.py +52 -0
  331. package/artemis-main/artemis/toolchain/descriptors.py +92 -0
  332. package/artemis-main/artemis/toolchain/resolver.py +185 -0
  333. package/artemis-main/artemis/tools/base.py +232 -0
  334. package/artemis-main/artemis/tools/command_tool.py +1240 -0
  335. package/artemis-main/artemis/tools/committee_prompts.json +5 -0
  336. package/artemis-main/artemis/tools/committee_tool.py +422 -0
  337. package/artemis-main/artemis/tools/diagnoser_submit_answer_tool.py +87 -0
  338. package/artemis-main/artemis/tools/diagnostic_tool.py +120 -0
  339. package/artemis-main/artemis/tools/explorer_tool.py +581 -0
  340. package/artemis-main/artemis/tools/history/__init__.py +398 -0
  341. package/artemis-main/artemis/tools/history/replay.py +120 -0
  342. package/artemis-main/artemis/tools/history/screenshot.py +139 -0
  343. package/artemis-main/artemis/tools/history/search.py +563 -0
  344. package/artemis-main/artemis/tools/image_processor_tool.py +124 -0
  345. package/artemis-main/artemis/tools/index.py +47 -0
  346. package/artemis-main/artemis/tools/log_tool.py +108 -0
  347. package/artemis-main/artemis/tools/mobile/launch_app.py +132 -0
  348. package/artemis-main/artemis/tools/mobile/log_utils.py +138 -0
  349. package/artemis-main/artemis/tools/mobile/ocr.py +202 -0
  350. package/artemis-main/artemis/tools/mobile/read_hierarchy.py +108 -0
  351. package/artemis-main/artemis/tools/mobile/read_logs.py +116 -0
  352. package/artemis-main/artemis/tools/mobile/search_logs.py +260 -0
  353. package/artemis-main/artemis/tools/object_detection_tool.py +244 -0
  354. package/artemis-main/artemis/tools/scratchpad.py +819 -0
  355. package/artemis-main/artemis/tools/system/adb_shell.py +31 -0
  356. package/artemis-main/artemis/tools/tool_wrapper.py +270 -0
  357. package/artemis-main/artemis/tools/video_tool.py +261 -0
  358. package/artemis-main/artemis/tools/wait_tool.py +97 -0
  359. package/artemis-main/artemis/utils/app_launch_utils.py +207 -0
  360. package/artemis-main/artemis/utils/coordinates.py +606 -0
  361. package/artemis-main/artemis/utils/credentials_validator.py +201 -0
  362. package/artemis-main/artemis/utils/cv_canvas.py +189 -0
  363. package/artemis-main/artemis/utils/cython_compat.py +45 -0
  364. package/artemis-main/artemis/utils/element_hit_test.py +80 -0
  365. package/artemis-main/artemis/utils/image_diff.py +335 -0
  366. package/artemis-main/artemis/utils/image_hash.py +80 -0
  367. package/artemis-main/artemis/utils/notes.py +470 -0
  368. package/artemis-main/artemis/utils/ocr_api.py +105 -0
  369. package/artemis-main/artemis/utils/ocr_xml_fusion.py +318 -0
  370. package/artemis-main/artemis/utils/plan_grammar.py +513 -0
  371. package/artemis-main/artemis/utils/python_executor.py +213 -0
  372. package/artemis-main/artemis/utils/startup_progress.py +60 -0
  373. package/artemis-main/artemis/utils/task_tree.py +1174 -0
  374. package/artemis-main/artemis/utils/text.py +37 -0
  375. package/artemis-main/artemis/utils/ui_filter.py +651 -0
  376. package/artemis-main/artemis/utils/video.py +685 -0
  377. package/artemis-main/artemis/utils/visualization.py +802 -0
  378. package/artemis-main/config/artemis.example.jsonc +12 -0
  379. package/artemis-main/mcp_server/README.md +111 -0
  380. package/artemis-main/mcp_server/__init__.py +21 -0
  381. package/artemis-main/mcp_server/__main__.py +20 -0
  382. package/artemis-main/mcp_server/background/__init__.py +15 -0
  383. package/artemis-main/mcp_server/background/task_runner.py +453 -0
  384. package/artemis-main/mcp_server/base.py +49 -0
  385. package/artemis-main/mcp_server/notifiers/__init__.py +74 -0
  386. package/artemis-main/mcp_server/notifiers/agentapi.py +289 -0
  387. package/artemis-main/mcp_server/notifiers/base.py +45 -0
  388. package/artemis-main/mcp_server/notifiers/composite.py +87 -0
  389. package/artemis-main/mcp_server/notifiers/desktop.py +108 -0
  390. package/artemis-main/mcp_server/notifiers/file.py +69 -0
  391. package/artemis-main/mcp_server/notifiers/script.py +90 -0
  392. package/artemis-main/mcp_server/notifiers/webhook.py +87 -0
  393. package/artemis-main/mcp_server/rules.md +68 -0
  394. package/artemis-main/mcp_server/server.py +106 -0
  395. package/artemis-main/mcp_server/tools/__init__.py +29 -0
  396. package/artemis-main/mcp_server/tools/device_state.py +107 -0
  397. package/artemis-main/mcp_server/tools/diagnose.py +1249 -0
  398. package/artemis-main/mcp_server/tools/inspect_trace.py +394 -0
  399. package/artemis-main/mcp_server/tools/task_manager.py +627 -0
  400. package/artemis-main/mcp_server/tools/task_runner.py +548 -0
  401. package/artemis-main/mcp_server/utils/__init__.py +15 -0
  402. package/artemis-main/mcp_server/utils/device_utils.py +180 -0
  403. package/artemis-main/mcp_server/utils/env_utils.py +65 -0
  404. package/artemis-main/packages/artemis-accessibility-helper/ArtemisAccessibilityHelper.apk +0 -0
  405. package/artemis-main/packages/artemis-accessibility-helper/app/build.gradle.kts +35 -0
  406. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/AndroidManifest.xml +49 -0
  407. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/A11yNode.java +274 -0
  408. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/ArtemisAccessibilityService.java +227 -0
  409. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/CommandServer.java +463 -0
  410. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/DisplayUtils.java +111 -0
  411. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/GestureController.java +232 -0
  412. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/HierarchyDumper.java +832 -0
  413. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenReceiver.java +36 -0
  414. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/TokenStore.java +38 -0
  415. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/java/com/artemis/helper/XmlUtils.java +102 -0
  416. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/values/strings.xml +4 -0
  417. package/artemis-main/packages/artemis-accessibility-helper/app/src/main/res/xml/accessibility_service_config.xml +10 -0
  418. package/artemis-main/packages/artemis-accessibility-helper/build.gradle.kts +3 -0
  419. package/artemis-main/packages/artemis-accessibility-helper/build_apk.sh +215 -0
  420. package/artemis-main/packages/artemis-accessibility-helper/debug.keystore +0 -0
  421. package/artemis-main/packages/artemis-accessibility-helper/gradle.properties +2 -0
  422. package/artemis-main/packages/artemis-accessibility-helper/helper_manifest.json +7 -0
  423. package/artemis-main/packages/artemis-accessibility-helper/settings.gradle.kts +17 -0
  424. package/artemis-main/packages/artemis-client/DESIGN.md +89 -0
  425. package/artemis-main/packages/artemis-client/README.md +112 -0
  426. package/artemis-main/packages/artemis-client/examples/basic.py +30 -0
  427. package/artemis-main/packages/artemis-client/pyproject.toml +36 -0
  428. package/artemis-main/packages/artemis-client/src/artemis_client/__init__.py +45 -0
  429. package/artemis-main/packages/artemis-client/src/artemis_client/client.py +401 -0
  430. package/artemis-main/packages/artemis-client/src/artemis_client/errors.py +66 -0
  431. package/artemis-main/packages/artemis-client/src/artemis_client/models.py +212 -0
  432. package/artemis-main/packages/artemis-client/src/artemis_client/py.typed +1 -0
  433. package/artemis-main/packages/artemis-client/src/artemis_client/transport.py +134 -0
  434. package/artemis-main/packages/artemis-client/tests/test_client.py +289 -0
  435. package/artemis-main/packages/artemis-client/tests/test_transport.py +85 -0
  436. package/artemis-main/pyproject.toml +259 -0
  437. package/artemis-main/pyright-core.json +17 -0
  438. package/artemis-main/scripts/check_dependency_sources.py +68 -0
  439. package/artemis-main/scripts/install_deps.ps1 +520 -0
  440. package/artemis-main/scripts/install_deps.sh +533 -0
  441. package/artemis-main/scripts/quality_ratchet.py +97 -0
  442. package/artemis-main/scripts/real_device_video_acceptance.py +483 -0
  443. package/artemis-main/scripts/run_edge_case_part.py +327 -0
  444. package/artemis-main/scripts/run_ui.py +242 -0
  445. package/artemis-main/scripts/start.ps1 +500 -0
  446. package/artemis-main/scripts/test_all_edge_cases.py +269 -0
  447. package/artemis-main/scripts/verify_concurrency_and_devices.py +385 -0
  448. package/artemis-main/setup.py +164 -0
  449. package/artemis-main/start.bat +35 -0
  450. package/artemis-main/start.sh +423 -0
  451. package/artemis-main/third_party/mobile_use/LICENSE +190 -0
  452. package/artemis-main/third_party/mobile_use/METADATA +27 -0
  453. package/artemis-main/third_party/mobile_use/NOTICE +12 -0
  454. package/artemis-main/third_party/mobile_use/__init__.py +19 -0
  455. package/artemis-main/third_party/mobile_use/agents/__init__.py +13 -0
  456. package/artemis-main/third_party/mobile_use/agents/hopper/__init__.py +13 -0
  457. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.md +22 -0
  458. package/artemis-main/third_party/mobile_use/agents/hopper/hopper.py +80 -0
  459. package/artemis-main/third_party/mobile_use/clients/__init__.py +13 -0
  460. package/artemis-main/third_party/mobile_use/clients/ui_automator_client.py +482 -0
  461. package/artemis-main/third_party/mobile_use/config/__init__.py +13 -0
  462. package/artemis-main/third_party/mobile_use/config/llm.py +183 -0
  463. package/artemis-main/third_party/mobile_use/config/output.py +184 -0
  464. package/artemis-main/third_party/mobile_use/context.py +119 -0
  465. package/artemis-main/third_party/mobile_use/controllers/__init__.py +13 -0
  466. package/artemis-main/third_party/mobile_use/controllers/platform_specific_commands_controller.py +151 -0
  467. package/artemis-main/third_party/mobile_use/controllers/types.py +92 -0
  468. package/artemis-main/third_party/mobile_use/controllers/unified_controller.py +183 -0
  469. package/artemis-main/third_party/mobile_use/graph.py +54 -0
  470. package/artemis-main/third_party/mobile_use/llm_service.py +193 -0
  471. package/artemis-main/third_party/mobile_use/main.py +130 -0
  472. package/artemis-main/third_party/mobile_use/sdk/__init__.py +13 -0
  473. package/artemis-main/third_party/mobile_use/sdk/agent.py +1060 -0
  474. package/artemis-main/third_party/mobile_use/sdk/builders/__init__.py +13 -0
  475. package/artemis-main/third_party/mobile_use/sdk/builders/agent_config_builder.py +225 -0
  476. package/artemis-main/third_party/mobile_use/sdk/builders/index.py +33 -0
  477. package/artemis-main/third_party/mobile_use/sdk/builders/task_request_builder.py +243 -0
  478. package/artemis-main/third_party/mobile_use/sdk/types/__init__.py +13 -0
  479. package/artemis-main/third_party/mobile_use/sdk/types/agent.py +98 -0
  480. package/artemis-main/third_party/mobile_use/sdk/types/exceptions.py +109 -0
  481. package/artemis-main/third_party/mobile_use/sdk/types/task.py +234 -0
  482. package/artemis-main/third_party/mobile_use/testing.py +59 -0
  483. package/artemis-main/third_party/mobile_use/tools/__init__.py +13 -0
  484. package/artemis-main/third_party/mobile_use/tools/index.py +44 -0
  485. package/artemis-main/third_party/mobile_use/tools/mobile/__init__.py +13 -0
  486. package/artemis-main/third_party/mobile_use/tools/mobile/launch_app.py +89 -0
  487. package/artemis-main/third_party/mobile_use/tools/tool_wrapper.py +52 -0
  488. package/artemis-main/third_party/mobile_use/utils/__init__.py +13 -0
  489. package/artemis-main/third_party/mobile_use/utils/app_launch_utils.py +217 -0
  490. package/artemis-main/third_party/mobile_use/utils/cli_helpers.py +60 -0
  491. package/artemis-main/third_party/mobile_use/utils/decorators.py +158 -0
  492. package/artemis-main/third_party/mobile_use/utils/file.py +31 -0
  493. package/artemis-main/third_party/mobile_use/utils/logger.py +216 -0
  494. package/artemis-main/third_party/mobile_use/utils/media.py +213 -0
  495. package/artemis-main/third_party/mobile_use/utils/shell_utils.py +39 -0
  496. package/artemis-main/third_party/mobile_use/utils/video.py +398 -0
  497. package/artemis-main/uv.lock +4908 -0
  498. package/bin/android-midscene-automation.js +1 -5
  499. package/bin/artemis-config.mjs +15 -0
  500. package/bin/artemis-embedded.py +56 -0
  501. package/bin/start-artemis.mjs +30 -0
  502. package/bin/start-dev.mjs +112 -0
  503. package/bin/test_artemis_embedded.py +44 -0
  504. package/package.json +4 -2
  505. package/server/artemis.ts +34 -0
  506. package/server/http-api.ts +12 -0
  507. package/src/App.vue +10 -5
  508. package/src/api.ts +5 -0
  509. package/src/appium-recorder/AppiumPage.vue +1 -1
  510. package/src/appium-recorder/components/ComponentInspector.vue +1 -1
  511. package/src/appium-recorder/components/FlowNodeSearch.vue +3 -3
  512. package/src/appium-recorder/components/ImageCheckDialog.vue +3 -3
  513. package/src/appium-recorder/components/RecorderWorkspace.vue +4 -4
  514. package/src/appium-recorder/flow-appearance.ts +4 -4
  515. package/src/components/AppSidebar.vue +8 -7
  516. package/src/components/MidsceneMaintenanceNotice.vue +17 -0
  517. package/src/components/analytics/AnalysisCharts.vue +4 -4
  518. package/src/components/analytics/ReportAnalysis.vue +1 -1
  519. package/src/components/generator/TestCaseFileUpload.vue +1 -1
  520. package/src/components/help/HelpCenter.vue +56 -37
  521. package/src/pages/AiGeneratorPage.vue +1 -1
  522. package/src/pages/ArtemisPage.vue +72 -0
  523. package/src/pages/ConfigPage.vue +18 -19
  524. package/src/style.css +340 -121
  525. package/src/types.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
1
  # 更新记录
2
+ ## v1.1.1
3
+ 更新README.md
4
+
5
+ ## v1.1.0
6
+ - [Artemis]修复自定义模型返回 `<think>` 思考标签导致 Hopper 等节点 JSON 解析失败的问题:非 Google 模型的 Pydantic 结构化输出接入统一清理、提取和校验流程,显式提供 JSON Schema,格式错误时限次要求模型纠正。
7
+ - [Artemis]修复 Flash 步骤摘要和历史压缩仍直接创建 Gemini 客户端的问题:非 Google 模型统一使用配置中的 summarizer 节点及其备用模型;模型初始化错误不再静默切换到 Gemini。
8
+ - [Artemis]修复 Artemis 使用 MiniMax、GLM 等非 Google 默认模型时,辅助检查节点仍强制调用 Gemini 并因缺少密钥导致任务启动失败的问题;支持这些节点继承默认模型或使用显式配置。
9
+ - [Artemis]集成 Google Artemis。
10
+ - [Midscene]Midscene 集成已停止日常维护,现有功能仍保留。
11
+
2
12
  ## v0.2.4
3
13
  - Midscene Android、Android Playground、Core、Playground、Shared 和 Web 模块统一升级至 1.14.0。
4
14
  - 修复 Midscene 测试脚本生成过程中切换“AI 生成 / 自定义步骤编排”会清空生成状态和结果的问题;生成任务继续在后台执行,模式切换后保留已生成步骤与代码。
package/README.md CHANGED
@@ -1,37 +1,21 @@
1
1
  # Android Midscene Automation
2
2
 
3
- 一个面向 Android App 的自动化测试工具,同时支持 Midscene AI 测试和 Appium 组件树录制回放。
3
+ 一个面向 Android App 的自动化测试工具,集成 Appium 组件树录制回放、Artemis 自然语言任务执行和 Midscene AI 测试。
4
4
 
5
5
  ## 界面预览
6
6
 
7
- ![](./screen/c1.jpg)
7
+ ![](./screen/1.jpg)
8
+ ![](./screen/2.jpg)
9
+ ![](./screen/3.jpg)
8
10
 
9
- ### Midscene
10
-
11
- ![](./screen/m1.jpg)
12
-
13
- ![](./screen/m2.jpg)
14
-
15
- ![](./screen/m3.jpg)
16
-
17
- ### Appium
18
-
19
- ![](./screen/a1.jpg)
20
-
21
- ![](./screen/a2.jpg)
22
-
23
- ![](./screen/a3.jpg)
24
-
25
- ![](./screen/a4.jpg)
26
-
27
- ![](./screen/a5.jpg)
28
11
 
29
12
  ## 支持的测试方式
30
13
 
31
14
  | 测试方式 | 页面入口 | 工作方式 | 模型要求 | 适用场景 |
32
15
  | --- | --- | --- | --- | --- |
33
- | Midscene | `Midscene > 测试脚本生成 / 自动化测试` | 使用自然语言生成和执行测试脚本,通过多模态模型理解设备画面 | **必须配置模型** | 页面元素难以稳定定位、希望使用自然语言快速编写测试 |
34
16
  | Appium | `Appium` | 读取 Android 组件树,按 selector、组件 ID 和流程图录制、回放 | **不需要配置任何模型** | 需要稳定、可重复、无模型消耗的传统自动化测试 |
17
+ | Artemis | `Artemis` | 使用自然语言描述目标,AI 自主规划并操作设备,记录步骤、结果和任务笔记 | **必须配置模型**,独立配置 | 探索性测试、多步骤业务任务、画面检查与数据收集 |
18
+ | Midscene | `Midscene > 测试脚本生成 / 自动化测试` | 使用自然语言生成和执行测试脚本,通过多模态模型理解设备画面 | **必须配置模型** | 页面元素难以稳定定位、希望使用自然语言快速编写测试 |
35
19
 
36
20
  使用 Midscene 前,请先进入“参数配置”完成 `Midscene 模型` 配置;需要 AI 生成脚本时,还要配置 `脚本优化模型`。模型配置不可用时,Midscene 脚本无法正常生成或执行。
37
21
 
@@ -39,10 +23,11 @@ Appium 方案完全不依赖大模型,不需要填写 Base URL、API Key、Mod
39
23
 
40
24
  ## 环境要求
41
25
 
42
- - Node.js 18+
43
- - npm
44
- - Android SDK / ADB,移动端自动化测试需要
45
- - Appium 3.x 和 UiAutomator2 Driver,仅 Appium 录制回放方式需要
26
+ - Node.js:运行主项目需要符合 Vite 7 的要求(20.19+ 或 22.12+);同时使用 Artemis 前端时按其 Angular 依赖要求准备 Node.js,当前集成使用 22.22.3+(22 LTS)。
27
+ - npm。
28
+ - Android SDK / ADB,移动端自动化测试需要。
29
+ - Appium 3.x 和 UiAutomator2 Driver,仅 Appium 录制回放方式需要。
30
+ - uv 和 Python 3.12+,仅 Artemis 需要。
46
31
 
47
32
  安装 Appium 相关依赖:
48
33
 
@@ -51,7 +36,141 @@ npm install -g appium@3.5.0
51
36
  appium driver install uiautomator2
52
37
  ```
53
38
 
54
- 使用 Appium 方式前需要运行 `appium` 启动服务;只使用 Midscene 时不需要安装或启动 Appium。
39
+ 使用 Appium 方式前需要运行 `appium` 启动服务;只使用 Artemis 或 Midscene 时不需要安装或启动 Appium。
40
+
41
+ ## Artemis 使用说明
42
+
43
+ ### 启动与控制台集成
44
+
45
+ 菜单中的 **Artemis** 在主内容区嵌入独立的 Artemis 控制台,支持切换菜单后保留页面状态。首次连接和“重新连接”都会检查服务;未启动或未允许嵌入时显示操作提示。
46
+
47
+ 1. Artemis 源码独立放在项目根目录的 `artemis-main/`,或通过 `ARTEMIS_PROJECT_DIR` 指定源码绝对路径。`artemis-main/` 源码随主项目的 Git / npm 包分发。本地 `config/artemis.jsonc`、`.env`、依赖环境和运行数据不提交、不打包;首次启动会从公开的 `config/artemis.example.jsonc` 生成本地配置,已有配置不会被覆盖。
48
+ 2. 安装 `uv`,准备 Python 3.12+、Node.js 22.22.3+(22 LTS)、ADB 和设备;Artemis 前端首次启动时会自动安装依赖并构建。
49
+ 3. 在项目根目录运行 `npm run dev`,或使用 `npx android-midscene-automation`,会同时启动主项目与 Artemis;首次会同步 Python 依赖并按需构建 Artemis 前端。启动完成后点击 **Artemis**。API Key、模型和设备在 Artemis 自身的配置中设置,不会自动复用 Midscene 的模型配置。
50
+
51
+ 检测到 Artemis 已运行时会复用该服务;按 Ctrl+C 会停止本次启动的服务,不会停止之前已运行的 Artemis。缺少源码或 Artemis 启动失败时会输出提示,主项目仍可使用。仍可通过 `npm run artemis` 单独启动 Artemis。主项目端口被占用时会明确报错,可通过 `npm run dev -- --port 5174` 指定其他端口,并自动为新启动的 Artemis 配置对应的嵌入来源。
52
+
53
+ 在 Artemis 的“系统设置 → 自定义配置”中点击“编辑 JSONC”,可直接修改并保存当前使用的 `artemis.jsonc`;支持注释和原有排版,保存前校验 JSONC、模型与智能体配置。文件已被其他操作修改时会阻止覆盖,保存失败时保留草稿。“取消编辑”放弃本次修改并重新加载文件。模型配置用于新任务,运行中的任务保持当前设置;API Key 和接口地址仍在 Artemis 的 `.env` 中配置。
54
+
55
+ 修改配置文件或 `.env` 后,点击自定义配置中的“刷新配置”,会重新校验 JSONC 并加载模型密钥和 Base URL,更新“已配置 / 未设置”状态,无需重启服务。刷新只检查本地配置,不调用模型 API 验证密钥;正在编辑草稿时按钮禁用,校验失败时保留当前已加载设置。
56
+
57
+ 专用启动入口仅绑定 `127.0.0.1:8000`,通过 CSP 允许 `localhost` / `127.0.0.1` 的 `5173`、`4173` 端口嵌入,并保留 Artemis 原有的 Host / Origin 校验。原来的 `artemis ui` 默认禁止 iframe;若已启动,需要先停止原服务再执行 `npm run artemis`。终端按 Ctrl+C 停止服务。
58
+
59
+ 可选环境变量:
60
+
61
+ | 变量 | 用途 |
62
+ | --- | --- |
63
+ | `ARTEMIS_PROJECT_DIR` | Artemis 源码目录,传给 `npm run dev` 或 `npm run artemis` |
64
+ | `ARTEMIS_PORT` | Artemis 服务端口,默认 `8000` |
65
+ | `ARTEMIS_EMBED_ORIGINS` | 允许嵌入的完整来源地址,逗号分隔;主项目使用其他端口时需设置,不接受通配符 |
66
+ | `ARTEMIS_URL` | 主项目后端连接的 Artemis 地址,默认 `http://127.0.0.1:8000`,传给 `npm run dev` 或 `npm run preview` |
67
+ | `ARTEMIS_AUTO_START` | 设置为 `0` 时,`npm run dev` 仅启动主项目;默认自动启动 Artemis |
68
+
69
+ 当前集成面向本机使用。Artemis 与 Midscene/Appium 的任务队列、设备锁和结果各自独立,请不要同时控制同一台设备。
70
+
71
+ ### 首次配置与执行
72
+
73
+ 1. 连接并解锁 Android 设备,开启 USB 调试,在终端运行 `adb devices -l`,确认设备状态为 `device`,并在手机上允许调试授权。
74
+ 2. 首次启动后,按下方说明配置 `artemis-main/.env` 和 `artemis-main/config/artemis.jsonc`,然后在“系统设置 → 自定义配置”点击“刷新配置”。
75
+ 3. 点击主项目菜单中的 **Artemis**,在 Artemis 控制台的设备选择入口选择实际连接的设备,再选择 **Flash** 或 **Pro** 执行模式。模式名称与模型名称不同,例如 Pro 模式也可以使用自定义的 MiniMax 模型。
76
+ 4. 输入自然语言任务并提交。任务应明确目标 App、操作范围和可观察的完成条件,例如:
77
+
78
+ > 打开 Android 设置,查看设备型号和 Android 版本,返回查到的信息后结束任务。
79
+
80
+ 5. 在执行视图查看步骤、模型调用、错误与结果;需要中止时使用停止按钮。选择历史任务可以查看对应记录。右上角中英文切换按钮用于切换控制台界面语言,任务描述可以使用中文。
81
+
82
+ ### 配置自定义模型
83
+
84
+ Artemis 不读取主项目“参数配置”中的 Midscene 模型。其模型名称、节点和备用模型写在 JSONC 中,API Key 与接口地址写在 `.env` 中:
85
+
86
+ | 你获得的参数 | Artemis 配置位置 | 示例字段 |
87
+ | --- | --- | --- |
88
+ | API Key | `artemis-main/.env` | `OPENAI_API_KEY` |
89
+ | Base URL | `artemis-main/.env` | `OPENAI_BASE_URL` |
90
+ | Model Name | `artemis-main/config/artemis.jsonc` | `default.model` 与 `default.fallback.model` |
91
+ | 接口类型 | `artemis-main/config/artemis.jsonc` | OpenAI 兼容接口使用 `provider: "openai"` |
92
+
93
+ 首次准备 `.env` 时,从项目根目录执行以下命令;如果文件已存在,直接编辑已有文件:
94
+
95
+ ```sh
96
+ cp -n artemis-main/.env.example artemis-main/.env
97
+ ```
98
+
99
+ 编辑 `.env`,使用模型服务商给出的 OpenAI 兼容接口地址和密钥。地址通常包含 `/v1`,应填写接口基地址,不要填写完整的 `/chat/completions` 请求路径:
100
+
101
+ ```dotenv
102
+ OPENAI_API_KEY=your-api-key
103
+ OPENAI_BASE_URL=https://your-provider.example/v1
104
+ ```
105
+
106
+ 通过“编辑 JSONC”修改本地配置,例如:
107
+
108
+ ```jsonc
109
+ {
110
+ "default": {
111
+ "provider": "openai",
112
+ "model": "your-model-name",
113
+ "fallback": {
114
+ "provider": "openai",
115
+ "model": "your-fallback-model-name"
116
+ }
117
+ },
118
+ "nodes": {}
119
+ }
120
+ ```
121
+
122
+ 将占位名称替换为服务商提供的实际模型名称。没有其他备用模型时,`fallback` 可以使用同一模型,但不会提供跨模型容错。`nodes` 用于覆盖指定节点的模型;没有覆盖的节点继承 `default`。切换提供方时也要检查原有节点及其 `fallback`,避免仍引用其他提供方的模型。
123
+
124
+ GLM、DeepSeek、MiniMax 等提供 OpenAI 兼容接口的服务可按此结构配置,但用于屏幕理解的模型还需要支持图片输入与所需的工具调用;接口兼容不代表每个模型型号都能完成设备任务。配置 Gemini 时使用 `provider: "google"`,并在 `.env` 中填写 `GOOGLE_API_KEY` 或 `GEMINI_API_KEY`。
125
+
126
+ 保存 JSONC 后点击“刷新配置”检查本地设置。出现“已配置”表示字段已读取,不代表 API Key、模型权限或多模态能力已通过在线验证。修改 Python 源码后需重启 Artemis;“刷新配置”不会重新加载源码。
127
+
128
+ ### Flash 与 Pro 模式
129
+
130
+ | 模式 | 执行方式 | 适用任务 | 笔记与计划 |
131
+ | --- | --- | --- | --- |
132
+ | Flash | 根据当前画面直接决策、操作,流程较简洁 | 打开页面、短流程操作、简单查询 | 当前未提供笔记读写工具,页签可能为空 |
133
+ | Pro | 先规划,再执行与校验,任务结束前进行最终检查 | 多步骤任务、需要过程证据或整理结果的测试 | 可生成计划和任务笔记 |
134
+
135
+ Pro 任务完成设备操作后,仍可能继续回看截图、检查结果、等待步骤摘要和生成录像。计划全部勾选不代表服务已完成收尾,以最终任务状态为准。
136
+
137
+ ### 笔记与计划
138
+
139
+ “笔记与计划”用于查看当前或历史任务中 AI 保存的记录,页面目前不提供直接编辑操作:
140
+
141
+ - `task_plan.md`:任务步骤和执行进度,显示待执行、执行中及完成状态。
142
+ - 其他笔记:保存采集数据、观察结果或任务总结;有多个文件时点击名称切换查看。
143
+
144
+ 在 Pro 模式的任务描述中明确要求记录,例如:
145
+
146
+ > 打开设置,查看设备型号和 Android 版本。执行前制定任务计划,将查到的信息保存到 device_info 笔记中,完成后更新计划并返回结果。
147
+
148
+ 笔记按任务保存,用于同一任务内的持续记忆,不会自动成为所有后续任务共享的知识库。
149
+
150
+ ### 执行记录与本地配置
151
+
152
+ 默认执行数据保存在 `artemis-main/traces/`,临时数据保存在 `artemis-main/scratch/`;自定义 `TRACES_PATH` 或运行参数时,以实际配置的输出位置为准。
153
+
154
+ | 路径 | 内容 | Git / npm 分发 |
155
+ | --- | --- | --- |
156
+ | `artemis-main/config/artemis.example.jsonc` | 不含密钥的公开默认配置 | 随源码分发 |
157
+ | `artemis-main/config/artemis.jsonc` | 本机实际使用的模型与智能体配置 | 已忽略,不提交、不打包 |
158
+ | `artemis-main/.env` | 本机模型密钥、Base URL 等设置 | 已忽略,不提交、不打包 |
159
+ | `artemis-main/traces/` | 执行数据库、步骤截图、录像、回放数据、任务笔记和计划 | 已忽略,不提交、不打包 |
160
+ | `artemis-main/scratch/` | 执行过程临时文件 | 已忽略,不提交、不打包 |
161
+
162
+ 执行记录写入本地不会自动执行 Git 提交或推送,正常 `git add .` 不会包含上述已忽略的文件。这里说明的是 Git/npm 分发范围;执行 AI 任务时,模型调用仍会向所配置的服务商发送任务所需的文本和图片。
163
+
164
+ ### Artemis 常见问题
165
+
166
+ - **控制台无法连接**:检查启动终端的日志,确认 `uv`、Python、Node.js 和前端构建依赖可用,再运行 `npm run artemis`。若使用其他端口,检查 `ARTEMIS_URL`、`ARTEMIS_PORT` 和嵌入来源是否一致。
167
+ - **模型仍显示“未设置”**:确认修改的是当前 `ARTEMIS_PROJECT_DIR` 下的 `.env` 与 `config/artemis.jsonc`,再点击“刷新配置”;主项目的 Midscene 配置不会同步到 Artemis。
168
+ - **没有实际设备**:运行 `adb devices -l`,检查 USB 调试授权、设备连接,以及 Artemis 的 `ADB_HOST`、`ADB_PORT`。任务使用 Artemis 中选择的设备。
169
+ - **视频工具链提示缺少 scrcpy / ffmpeg**:在“系统设置”的视频工具链检查中查看缺失项目,安装后确认启动 Artemis 的终端能找到工具;终端 PATH 改变后重新启动服务。
170
+ - **任务看起来没有结束**:查看最近步骤和日志,区分正在操作、等待模型、错误暂停与 Pro 最终检查。记录任务 ID 可用于定位日志;需要结束当前任务时使用停止按钮。
171
+ - **自定义模型输出解析失败**:本项目已为非 Google 模型的 Pydantic 结构化输出接入思考标签清理、JSON 提取和校验,格式错误时要求模型纠正一次;持续错误仍会报告失败。纯文本步骤摘要也会清理思考内容,避免将其计入摘要长度。
172
+
173
+ 上述模型适配修复属于本项目集成源码的修改,并不代表 Artemis 上游已包含相同修复。
55
174
 
56
175
  ## 启动
57
176
 
@@ -75,6 +194,7 @@ npx android-midscene-automation --port 5174
75
194
 
76
195
  ## 功能文档
77
196
 
197
+ - [Artemis 使用说明](#artemis-使用说明)
78
198
  - [Appium 录制器使用说明](#appium-录制器使用说明)
79
199
  - [流程节点操作说明](./流程节点操作说明.md)
80
200
  - [AI 识别操作说明](./AI识别操作说明.md)
@@ -112,11 +232,11 @@ npm run dev
112
232
  http://127.0.0.1:5173/
113
233
  ```
114
234
 
115
- `npm run dev` 会同时启动前端页面和本地后端 API。后端不是独立进程,而是在 `vite.config.ts` 中通过 `server/http-api.ts` 挂载到 Vite dev server 的 Connect middleware。
235
+ `npm run dev` 会同时启动前端页面、本地后端 API 和独立的 Artemis 服务。主项目后端不是独立进程,而是在 `vite.config.ts` 中通过 `server/http-api.ts` 挂载到 Vite dev server 的 Connect middleware。
116
236
 
117
237
  ## 模型配置
118
238
 
119
- 模型配置仅用于 Midscene 和 AI 脚本生成,Appium 录制与回放不读取模型配置。首次使用 Midscene 时进入页面的“参数配置”:
239
+ 本节的“参数配置”仅用于 Midscene 和 AI 脚本生成,Appium 录制与回放不读取这些模型配置。Artemis 使用自己的 JSONC 与 `.env`,详见 [Artemis 使用说明](#artemis-使用说明)。首次使用 Midscene 时进入页面的“参数配置”:
120
240
 
121
241
  - `运行配置`:可选指定 Android SDK 根目录和 Appium 回放报告目录;留空时使用系统 SDK 与默认 `output` 目录。
122
242
  - `Midscene模型`:执行测试脚本时使用,支持“自定义提供方”和“使用 Codex”。
@@ -1382,6 +1502,16 @@ Linux: ~/.local/share/android-midscene-automation
1382
1502
 
1383
1503
  # 项目更新记录
1384
1504
 
1505
+ ## v1.1.1
1506
+ 更新README.md
1507
+
1508
+ ## v1.1.0
1509
+ - [Artemis]修复自定义模型返回 `<think>` 思考标签导致 Hopper 等节点 JSON 解析失败的问题:非 Google 模型的 Pydantic 结构化输出接入统一清理、提取和校验流程,显式提供 JSON Schema,格式错误时限次要求模型纠正。
1510
+ - [Artemis]修复 Flash 步骤摘要和历史压缩仍直接创建 Gemini 客户端的问题:非 Google 模型统一使用配置中的 summarizer 节点及其备用模型;模型初始化错误不再静默切换到 Gemini。
1511
+ - [Artemis]修复 Artemis 使用 MiniMax、GLM 等非 Google 默认模型时,辅助检查节点仍强制调用 Gemini 并因缺少密钥导致任务启动失败的问题;支持这些节点继承默认模型或使用显式配置。
1512
+ - [Artemis]集成 Google Artemis。
1513
+ - [Midscene]Midscene 集成已停止日常维护,现有功能仍保留。
1514
+
1385
1515
  ## v0.2.4
1386
1516
  - Midscene Android、Android Playground、Core、Playground、Shared 和 Web 模块统一升级至 1.14.0。
1387
1517
  - 修复 Midscene 测试脚本生成过程中切换“AI 生成 / 自定义步骤编排”会清空生成状态和结果的问题;生成任务继续在后台执行,模式切换后保留已生成步骤与代码。
@@ -0,0 +1,15 @@
1
+ .git
2
+ .github
3
+ .venv
4
+ .pytest_cache
5
+ .ruff_cache
6
+ **/__pycache__
7
+ **/*.pyc
8
+ apps/showcase_ui/.angular
9
+ apps/showcase_ui/dist
10
+ apps/showcase_ui/node_modules
11
+ build
12
+ dist
13
+ traces
14
+ .env
15
+ *.log
@@ -0,0 +1,34 @@
1
+ # ==============================================================================
2
+ # Artemis Environment Configuration Template
3
+ # ==============================================================================
4
+ # Copy this file to .env and fill in your API credentials:
5
+ # cp .env.example .env
6
+
7
+ # LLM Providers (Configure at least one)
8
+ GEMINI_API_KEY=
9
+ GOOGLE_API_KEY=
10
+ OPENAI_API_KEY=
11
+ # OpenAI-compatible endpoint for GLM, DeepSeek, or other providers
12
+ OPENAI_BASE_URL=
13
+ ANTHROPIC_API_KEY=
14
+ OPEN_ROUTER_API_KEY=
15
+ XAI_API_KEY=
16
+
17
+ # Google Cloud Vision OCR (Optional - for advanced OCR processing)
18
+ OCR_API_KEY=
19
+
20
+ # Android ADB Connectivity (Optional - defaults to 127.0.0.1:5037)
21
+ ADB_HOST=127.0.0.1
22
+ ADB_PORT=5037
23
+ # ADB_DEVICE_SERIAL=
24
+ # Keep the display awake, falling back to a wake lock or safe heartbeat when needed.
25
+ # Set to false if Artemis is used with a personal device whose screen should time out.
26
+ ARTEMIS_KEEP_DEVICE_AWAKE=true
27
+ # UI hierarchy backend: auto (Accessibility Helper, UIAutomator2 fallback) | helper | uiautomator
28
+ ARTEMIS_HIERARCHY_BACKEND=auto
29
+ # Let tasks install / upgrade the Accessibility Helper APK on a device they hold.
30
+ # Set to false on shared or personal phones: then only `artemis helper install` installs it.
31
+ ARTEMIS_HELPER_AUTO_INSTALL=true
32
+
33
+ # Artemis Execution Defaults (flash or pro)
34
+ ARTEMIS_DEFAULT_PROFILE=flash
@@ -0,0 +1,35 @@
1
+ # Contributing to ARTEMIS
2
+
3
+ Thank you for your interest in contributing to **ARTEMIS**! We welcome and appreciate all forms of contributions—whether it's reporting bugs, proposing new features, improving documentation, or submitting code.
4
+
5
+ ---
6
+
7
+ ## 🤝 Ways to Contribute
8
+
9
+ - **🐛 Report Bugs & Suggest Features**: If you find an issue or have an idea to improve ARTEMIS, please open an [Issue](https://github.com/google/artemis/issues).
10
+ - **💡 Submit Pull Requests**:
11
+ 1. Fork the repository and create your feature/fix branch (`git checkout -b feat/my-feature`).
12
+ 2. Make your changes and verify with `make test`, `make lint`, and `make typecheck`.
13
+ 3. Open a Pull Request with a brief summary of your work.
14
+ - **💬 Community & Discussion**: Join our [Discord Community](https://discord.gg/wF2FN4WHGY) to chat with maintainers, ask questions, or share feedback.
15
+
16
+ ---
17
+
18
+ Every contribution—big or small—helps make ARTEMIS better. Thank you for building with us!
19
+
20
+ ## Test layers
21
+
22
+ `make test` is the required, deterministic suite. It does not need an Android
23
+ device, model credentials, or the optional private cloud service. This is the
24
+ same suite used by pull-request CI.
25
+
26
+ - `make test-integration` runs cross-component tests that may need configured
27
+ model credentials.
28
+ - `make test-device` runs Android and end-to-end tests and therefore requires
29
+ an attached, authorized device or emulator.
30
+ - `make test-all` collects every test tree and is intended for a fully
31
+ provisioned maintainer environment.
32
+
33
+ Tests that require external state must carry the appropriate `android`,
34
+ `cloud`, `manual`, or `e2e` marker. They must remain safely collectable when
35
+ that dependency is unavailable.
@@ -0,0 +1,68 @@
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
+ FROM node:22-bookworm-slim AS frontend-builder
16
+
17
+ WORKDIR /build/apps/showcase_ui
18
+ COPY apps/showcase_ui/package.json apps/showcase_ui/package-lock.json ./
19
+ RUN npm ci
20
+ COPY apps/showcase_ui/angular.json apps/showcase_ui/tsconfig*.json ./
21
+ COPY apps/showcase_ui/public/ ./public/
22
+ COPY apps/showcase_ui/src/ ./src/
23
+ RUN npm run build
24
+
25
+
26
+ FROM python:3.12-slim AS wheel-builder
27
+
28
+ WORKDIR /build
29
+ COPY artemis/ ./artemis/
30
+ COPY apps/ ./apps/
31
+ COPY mcp_server/ ./mcp_server/
32
+ COPY third_party/ ./third_party/
33
+ COPY packages/artemis-client/ ./packages/artemis-client/
34
+ COPY config/ ./config/
35
+ COPY pyproject.toml setup.py README.md LICENSE ./
36
+ COPY --from=frontend-builder /build/apps/showcase_ui/dist/ ./apps/showcase_ui/dist/
37
+
38
+ # Build wheels for the runtime image.
39
+ RUN python -m pip wheel --no-cache-dir --no-deps --wheel-dir /wheels ./packages/artemis-client \
40
+ && python -m pip wheel --no-cache-dir --no-deps --wheel-dir /wheels .
41
+
42
+
43
+ FROM python:3.12-slim
44
+
45
+ WORKDIR /app
46
+
47
+ RUN apt-get update && apt-get install -y --no-install-recommends \
48
+ adb \
49
+ curl \
50
+ git \
51
+ && rm -rf /var/lib/apt/lists/*
52
+
53
+ COPY --from=wheel-builder /wheels/ /wheels/
54
+ RUN pip install --no-cache-dir /wheels/artemis_client-*.whl \
55
+ && pip install --no-cache-dir /wheels/artemis-*.whl \
56
+ && rm -rf /wheels
57
+
58
+ ENV PYTHONUNBUFFERED=1
59
+ ENV ARTEMIS_APP_DIR=/app
60
+ ENV PORT=8080
61
+
62
+ EXPOSE 8080
63
+
64
+ # The console has no user authentication: publish the port to loopback only,
65
+ # e.g. `docker run -p 127.0.0.1:8080:8080 ...`, and reach it remotely through
66
+ # a Tailscale/SSH tunnel. (0.0.0.0 here is container-internal and required
67
+ # for the port mapping to work.)
68
+ CMD ["uvicorn", "apps.admin_console.server:app", "--host", "0.0.0.0", "--port", "8080"]
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ https://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright 2026 Google LLC.
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ https://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.