veadk-python 0.2.28__tar.gz → 0.2.29__tar.gz

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 (254) hide show
  1. {veadk_python-0.2.28/veadk_python.egg-info → veadk_python-0.2.29}/PKG-INFO +2 -1
  2. {veadk_python-0.2.28 → veadk_python-0.2.29}/pyproject.toml +2 -1
  3. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/consts.py +1 -1
  4. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/mcp_tool.py +2 -3
  5. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/mcp_toolset.py +2 -3
  6. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/utils.py +33 -0
  7. veadk_python-0.2.29/veadk/tools/builtin_tools/mobile_run.py +523 -0
  8. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/volcengine_sign.py +4 -7
  9. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/version.py +1 -1
  10. {veadk_python-0.2.28 → veadk_python-0.2.29/veadk_python.egg-info}/PKG-INFO +2 -1
  11. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/SOURCES.txt +1 -0
  12. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/requires.txt +1 -0
  13. {veadk_python-0.2.28 → veadk_python-0.2.29}/LICENSE +0 -0
  14. {veadk_python-0.2.28 → veadk_python-0.2.29}/README.md +0 -0
  15. {veadk_python-0.2.28 → veadk_python-0.2.29}/setup.cfg +0 -0
  16. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_agent.py +0 -0
  17. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_cloud.py +0 -0
  18. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_evaluator.py +0 -0
  19. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_knowledgebase.py +0 -0
  20. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_long_term_memory.py +0 -0
  21. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_misc.py +0 -0
  22. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_multiple_agents.py +0 -0
  23. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_runner.py +0 -0
  24. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_runtime_data_collecting.py +0 -0
  25. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_short_term_memory.py +0 -0
  26. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_tracing.py +0 -0
  27. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_a2a_middlewares.py +0 -0
  28. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_auth_config.py +0 -0
  29. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_function_tool.py +0 -0
  30. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_mcp_tool.py +0 -0
  31. {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_mcp_toolset.py +0 -0
  32. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/__init__.py +0 -0
  33. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/__init__.py +0 -0
  34. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/agent_card.py +0 -0
  35. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/remote_ve_agent.py +0 -0
  36. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/utils/__init__.py +0 -0
  37. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/utils/agent_to_a2a.py +0 -0
  38. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_a2a_server.py +0 -0
  39. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_agent_executor.py +0 -0
  40. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_middlewares.py +0 -0
  41. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_task_store.py +0 -0
  42. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agent.py +0 -0
  43. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agent_builder.py +0 -0
  44. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/loop_agent.py +0 -0
  45. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/parallel_agent.py +0 -0
  46. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/sequential_agent.py +0 -0
  47. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/__init__.py +0 -0
  48. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/base_auth.py +0 -0
  49. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/ve_credential_service.py +0 -0
  50. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/__init__.py +0 -0
  51. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/apmplus_veauth.py +0 -0
  52. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/ark_veauth.py +0 -0
  53. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/base_veauth.py +0 -0
  54. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/cozeloop_veauth.py +0 -0
  55. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/opensearch_veauth.py +0 -0
  56. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/postgresql_veauth.py +0 -0
  57. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/prompt_pilot_veauth.py +0 -0
  58. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/speech_veauth.py +0 -0
  59. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/utils.py +0 -0
  60. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/vesearch_veauth.py +0 -0
  61. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/viking_mem0_veauth.py +0 -0
  62. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/__init__.py +0 -0
  63. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli.py +0 -0
  64. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_clean.py +0 -0
  65. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_create.py +0 -0
  66. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_deploy.py +0 -0
  67. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_eval.py +0 -0
  68. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_init.py +0 -0
  69. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_kb.py +0 -0
  70. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_pipeline.py +0 -0
  71. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_prompt.py +0 -0
  72. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_rl.py +0 -0
  73. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_update.py +0 -0
  74. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_uploadevalset.py +0 -0
  75. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_web.py +0 -0
  76. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/README.md +0 -0
  77. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/arkworkspace.toml +0 -0
  78. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/data/demo_dataset.jsonl +0 -0
  79. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/job.py +0 -0
  80. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/job.yaml +0 -0
  81. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/random_reward.py +0 -0
  82. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/raw_async_veadk_rollout.py +0 -0
  83. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/test_utils.py +0 -0
  84. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/requirements.txt +0 -0
  85. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/test_faas.py +0 -0
  86. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/__init__.py +0 -0
  87. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/cloud_agent_engine.py +0 -0
  88. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/cloud_app.py +0 -0
  89. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/config.py +0 -0
  90. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/__init__.py +0 -0
  91. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/auth_configs.py +0 -0
  92. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/database_configs.py +0 -0
  93. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/model_configs.py +0 -0
  94. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/tool_configs.py +0 -0
  95. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/tracing_configs.py +0 -0
  96. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/__init__.py +0 -0
  97. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/adk_evaluator/__init__.py +0 -0
  98. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/adk_evaluator/adk_evaluator.py +0 -0
  99. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/base_evaluator.py +0 -0
  100. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/deepeval_evaluator/__init__.py +0 -0
  101. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +0 -0
  102. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/eval_set_file_loader.py +0 -0
  103. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/eval_set_recorder.py +0 -0
  104. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/types.py +0 -0
  105. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/utils/prometheus.py +0 -0
  106. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/__init__.py +0 -0
  107. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/__init__.py +0 -0
  108. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/ve_apig.py +0 -0
  109. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/ve_apig_utils.py +0 -0
  110. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_code_pipeline/__init__.py +0 -0
  111. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +0 -0
  112. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cozeloop/__init__.py +0 -0
  113. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cozeloop/ve_cozeloop.py +0 -0
  114. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cr/__init__.py +0 -0
  115. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cr/ve_cr.py +0 -0
  116. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/__init__.py +0 -0
  117. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/cookiecutter.json +0 -0
  118. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +0 -0
  119. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +0 -0
  120. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +0 -0
  121. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +0 -0
  122. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +0 -0
  123. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +0 -0
  124. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +0 -0
  125. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +0 -0
  126. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +0 -0
  127. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +0 -0
  128. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +0 -0
  129. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/ve_faas.py +0 -0
  130. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/ve_faas_utils.py +0 -0
  131. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/cookiecutter.json +0 -0
  132. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +0 -0
  133. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +0 -0
  134. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +0 -0
  135. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +0 -0
  136. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +0 -0
  137. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +0 -0
  138. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +0 -0
  139. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +0 -0
  140. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +0 -0
  141. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +0 -0
  142. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +0 -0
  143. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
  144. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +0 -0
  145. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +0 -0
  146. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +0 -0
  147. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +0 -0
  148. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +0 -0
  149. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +0 -0
  150. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +0 -0
  151. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/__init__.py +0 -0
  152. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_config.py +0 -0
  153. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_mixins.py +0 -0
  154. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_processor.py +0 -0
  155. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/function_tool.py +0 -0
  156. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/identity_client.py +0 -0
  157. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/models.py +0 -0
  158. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/token_manager.py +0 -0
  159. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_prompt_pilot/__init__.py +0 -0
  160. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +0 -0
  161. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/__init__.py +0 -0
  162. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/utils.py +0 -0
  163. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/ve_tls.py +0 -0
  164. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tos/ve_tos.py +0 -0
  165. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_viking_db_memory/__init__.py +0 -0
  166. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +0 -0
  167. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/__init__.py +0 -0
  168. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/__init__.py +0 -0
  169. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/base_backend.py +0 -0
  170. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/in_memory_backend.py +0 -0
  171. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/opensearch_backend.py +0 -0
  172. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/redis_backend.py +0 -0
  173. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/utils.py +0 -0
  174. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +0 -0
  175. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/entry.py +0 -0
  176. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/knowledgebase.py +0 -0
  177. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/__init__.py +0 -0
  178. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory.py +0 -0
  179. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/__init__.py +0 -0
  180. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/base_backend.py +0 -0
  181. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/in_memory_backend.py +0 -0
  182. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/mem0_backend.py +0 -0
  183. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/opensearch_backend.py +0 -0
  184. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/redis_backend.py +0 -0
  185. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +0 -0
  186. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory.py +0 -0
  187. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/__init__.py +0 -0
  188. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/base_backend.py +0 -0
  189. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/mysql_backend.py +0 -0
  190. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/postgresql_backend.py +0 -0
  191. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/sqlite_backend.py +0 -0
  192. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_processor.py +0 -0
  193. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/processors/__init__.py +0 -0
  194. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/processors/base_run_processor.py +0 -0
  195. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/__init__.py +0 -0
  196. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/agent_default_prompt.py +0 -0
  197. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_evaluator.py +0 -0
  198. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_memory_processor.py +0 -0
  199. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_optimization.py +0 -0
  200. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/runner.py +0 -0
  201. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/__init__.py +0 -0
  202. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/__init__.py +0 -0
  203. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/agent_authorization.py +0 -0
  204. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/generate_image.py +0 -0
  205. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/image_edit.py +0 -0
  206. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/image_generate.py +0 -0
  207. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/lark.py +0 -0
  208. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/las.py +0 -0
  209. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/link_reader.py +0 -0
  210. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/llm_shield.py +0 -0
  211. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/load_knowledgebase.py +0 -0
  212. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/mcp_router.py +0 -0
  213. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/run_code.py +0 -0
  214. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/tts.py +0 -0
  215. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/vesearch.py +0 -0
  216. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/video_generate.py +0 -0
  217. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/web_scraper.py +0 -0
  218. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/web_search.py +0 -0
  219. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/demo_tools.py +0 -0
  220. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/load_knowledgebase_tool.py +0 -0
  221. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/__init__.py +0 -0
  222. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/trusted_mcp_session_manager.py +0 -0
  223. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/trusted_mcp_toolset.py +0 -0
  224. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/__init__.py +0 -0
  225. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/browser_sandbox.py +0 -0
  226. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/code_sandbox.py +0 -0
  227. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/computer_sandbox.py +0 -0
  228. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/__init__.py +0 -0
  229. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/base_tracer.py +0 -0
  230. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/__init__.py +0 -0
  231. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/attributes.py +0 -0
  232. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +0 -0
  233. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +0 -0
  234. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +0 -0
  235. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/types.py +0 -0
  236. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/__init__.py +0 -0
  237. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/apmplus_exporter.py +0 -0
  238. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/base_exporter.py +0 -0
  239. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/cozeloop_exporter.py +0 -0
  240. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/inmemory_exporter.py +0 -0
  241. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/tls_exporter.py +0 -0
  242. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/opentelemetry_tracer.py +0 -0
  243. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/telemetry.py +0 -0
  244. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/types.py +0 -0
  245. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/__init__.py +0 -0
  246. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/audio_manager.py +0 -0
  247. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/auth.py +0 -0
  248. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/logger.py +0 -0
  249. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/mcp_utils.py +0 -0
  250. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/misc.py +0 -0
  251. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/patches.py +0 -0
  252. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/dependency_links.txt +0 -0
  253. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/entry_points.txt +0 -0
  254. {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: veadk-python
3
- Version: 0.2.28
3
+ Version: 0.2.29
4
4
  Summary: Volcengine agent development kit, integrations with Volcengine cloud services.
5
5
  Author-email: Yaozheng Fang <fangyozheng@gmail.com>, Guodong Li <cu.eric.lee@gmail.com>, Zhi Han <sliverydayday@gmail.com>, Meng Wang <mengwangwm@gmail.com>
6
6
  License: Apache License
@@ -212,6 +212,7 @@ Requires-Dist: pydantic-settings>=2.10.1
212
212
  Requires-Dist: a2a-sdk>=0.3.0
213
213
  Requires-Dist: deprecated>=1.2.18
214
214
  Requires-Dist: google-adk>=1.10.0
215
+ Requires-Dist: google-adk<=1.19.0
215
216
  Requires-Dist: litellm>=1.74.3
216
217
  Requires-Dist: loguru>=0.7.3
217
218
  Requires-Dist: opentelemetry-exporter-otlp>=1.35.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "veadk-python"
3
- version = "0.2.28"
3
+ version = "0.2.29"
4
4
  description = "Volcengine agent development kit, integrations with Volcengine cloud services."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -16,6 +16,7 @@ dependencies = [
16
16
  "a2a-sdk>=0.3.0", # For Google Agent2Agent protocol
17
17
  "deprecated>=1.2.18",
18
18
  "google-adk>=1.10.0", # For basic agent architecture
19
+ "google-adk<=1.19.0", # For basic agent architecture
19
20
  "litellm>=1.74.3", # For model inference
20
21
  "loguru>=0.7.3", # For better logging
21
22
  "opentelemetry-exporter-otlp>=1.35.0",
@@ -28,7 +28,7 @@ DEFAULT_MODEL_EXTRA_CONFIG = {
28
28
  "veadk-source": "veadk",
29
29
  "veadk-version": VERSION,
30
30
  "User-Agent": f"VeADK/{VERSION}",
31
- "X-Client-Request-Id": f"veadk/{VERSION}",
31
+ "X-Client-Request-Id": getenv("MODEL_AGENT_CLIENT_REQ_ID", f"veadk/{VERSION}"),
32
32
  },
33
33
  "extra_body": {
34
34
  "caching": {
@@ -24,14 +24,13 @@ from google.adk.tools.base_tool import BaseTool
24
24
  from google.adk.tools.tool_context import ToolContext
25
25
  from google.adk.tools._gemini_schema_util import _to_gemini_schema
26
26
  from google.adk.tools.mcp_tool.mcp_session_manager import MCPSessionManager
27
- from google.adk.tools.mcp_tool.mcp_session_manager import retry_on_closed_resource
28
27
 
29
28
  from veadk.integrations.ve_identity.auth_config import VeIdentityAuthConfig
30
29
  from veadk.integrations.ve_identity.auth_mixins import (
31
30
  VeIdentityAuthMixin,
32
31
  AuthRequiredException,
33
32
  )
34
- from veadk.integrations.ve_identity.utils import generate_headers
33
+ from veadk.integrations.ve_identity.utils import generate_headers, retry_on_errors
35
34
  from veadk.utils.logger import get_logger
36
35
 
37
36
  logger = get_logger(__name__)
@@ -157,7 +156,7 @@ class VeIdentityMcpTool(VeIdentityAuthMixin, BaseTool):
157
156
  args=args, tool_context=tool_context, credential=credential
158
157
  )
159
158
 
160
- @retry_on_closed_resource
159
+ @retry_on_errors
161
160
  async def _run_async_impl(
162
161
  self, *, args, tool_context: ToolContext, credential: AuthCredential
163
162
  ):
@@ -29,7 +29,6 @@ from mcp import StdioServerParameters, ClientSession
29
29
  from mcp.types import ListToolsResult
30
30
 
31
31
  from google.adk.tools.mcp_tool.mcp_session_manager import (
32
- retry_on_closed_resource,
33
32
  SseConnectionParams,
34
33
  StdioConnectionParams,
35
34
  StreamableHTTPConnectionParams,
@@ -43,7 +42,7 @@ from google.adk.agents.readonly_context import ReadonlyContext
43
42
  from veadk.integrations.ve_identity.auth_config import VeIdentityAuthConfig
44
43
  from veadk.integrations.ve_identity.auth_mixins import VeIdentityAuthMixin
45
44
  from veadk.integrations.ve_identity.mcp_tool import VeIdentityMcpTool
46
- from veadk.integrations.ve_identity.utils import generate_headers
45
+ from veadk.integrations.ve_identity.utils import generate_headers, retry_on_errors
47
46
 
48
47
  logger = logging.getLogger(__name__)
49
48
 
@@ -158,7 +157,7 @@ class VeIdentityMcpToolset(VeIdentityAuthMixin, BaseToolset):
158
157
  errlog=errlog,
159
158
  )
160
159
 
161
- @retry_on_closed_resource
160
+ @retry_on_errors
162
161
  @override
163
162
  async def get_tools(
164
163
  self,
@@ -16,12 +16,17 @@
16
16
 
17
17
  from __future__ import annotations
18
18
  import base64
19
+ import functools
19
20
  from typing import Optional
20
21
 
21
22
  from google.adk.events import Event
22
23
  from google.adk.auth import AuthConfig
23
24
  from google.adk.auth.auth_credential import AuthCredential
24
25
 
26
+ from veadk.utils.logger import get_logger
27
+
28
+ logger = get_logger(__name__)
29
+
25
30
 
26
31
  def is_pending_auth_event(event: Event) -> bool:
27
32
  """Check if an ADK event represents a pending authentication request.
@@ -149,3 +154,31 @@ def generate_headers(credential: AuthCredential) -> Optional[dict[str, str]]:
149
154
  pass
150
155
 
151
156
  return headers
157
+
158
+
159
+ def retry_on_errors(func):
160
+ """Decorator to automatically retry action when MCP session errors occur.
161
+
162
+ When MCP session errors occur, the decorator will automatically retry the
163
+ action once. The create_session method will handle creating a new session
164
+ if the old one was disconnected.
165
+
166
+ Args:
167
+ func: The function to decorate.
168
+
169
+ Returns:
170
+ The decorated function.
171
+ """
172
+
173
+ @functools.wraps(func) # Preserves original function metadata
174
+ async def wrapper(self, *args, **kwargs):
175
+ try:
176
+ return await func(self, *args, **kwargs)
177
+ except Exception as e:
178
+ # If an error is thrown, we will retry the function to reconnect to the
179
+ # server. create_session will handle detecting and replacing disconnected
180
+ # sessions.
181
+ logger.info("Retrying %s due to error: %s", func.__name__, e)
182
+ return await func(self, *args, **kwargs)
183
+
184
+ return wrapper
@@ -0,0 +1,523 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
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
+ """
16
+ Mobile Automation Tool (Mobile Use Tool)
17
+ =======================================
18
+ Purpose: Execute automated tasks on a virtual mobile device via the Volcano Engine
19
+ mobile-use service (app operations, screenshots, account actions, etc.). An Agent plans
20
+ the workflow in the background, supporting custom user instructions and system constraints.
21
+
22
+ Prerequisites:
23
+ 1. Subscribe to the Cloud Phone service with your Volcano Engine account to obtain
24
+ `product_id` and `pod_id`.
25
+ 2. Required environment variables (set before running):
26
+ - VOLCENGINE_ACCESS_KEY: Volcano Engine access key AK
27
+ - VOLCENGINE_SECRET_KEY: Volcano Engine secret key SK
28
+ - TOOL_MOBILE_USE_TOOL_ID: Product ID and Virtual phone Pod identifier (from the console). For complex
29
+ tasks requiring parallel execution across multiple pods, provide multiple IDs. available in the console: https://console.volcengine.com/ACEP/)
30
+ "业务ID" is product_id, "实例 ID" is pod_id. tool_id = {product_id}-{pod_id}.
31
+
32
+
33
+ YAML configuration format
34
+ tool:
35
+ mobile_use:
36
+ tool_id:
37
+ - product_id-pod_id
38
+ - product_id-pod_id
39
+
40
+ volcengine:
41
+ access_key: xxx
42
+ secret_key: xxx
43
+
44
+ Core usage (closure functions):
45
+ 1. Initialize tool configuration (outer function, run once):
46
+ Pass the system prompt, timeout, and other static configurations. Environment validation
47
+ and Agent configuration are handled internally.
48
+
49
+ 2. Execute specific tasks (inner function, callable multiple times):
50
+ Pass user task instructions; the initialized configuration is reused to perform automation
51
+ and return results.
52
+
53
+ Example code:
54
+ ---------
55
+ import asyncio
56
+ from this_module import create_mobile_use_tool
57
+
58
+ # 1. Initialize the tool (static configuration, run once)
59
+ system_prompt = '''
60
+ You are a mobile testing agent. Follow these rules:
61
+ 1. Strictly follow user instructions; do not add unrelated steps.
62
+ 2. Avoid unauthorized access; follow the principle of least privilege.
63
+ 3. Return a clear result describing whether key actions succeeded.
64
+ '''
65
+ mobile_tool = create_mobile_use_tool(
66
+ system_prompt=system_prompt,
67
+ timeout_seconds=300, # 5-minute task timeout
68
+ step_interval_seconds=3 # 3-second polling interval
69
+ )
70
+
71
+ # 2. Reuse the configuration to execute multiple tasks (asynchronous)
72
+ async def main():
73
+ # Task 1: Open the app and take a screenshot
74
+ result1 = await mobile_tool(
75
+ "Open Douyin, wait for the home page to load, then capture a full-screen screenshot"
76
+ )
77
+ print("Task 1 result:", result1)
78
+
79
+ # Task 2: Search and follow an account (reusing the same system prompt and timeouts)
80
+ result2 = await mobile_tool(
81
+ "Search 'Volcano Engine' in Douyin, find the official account, and tap Follow"
82
+ )
83
+ print("Task 2 result:", result2)
84
+
85
+ if __name__ == "__main__":
86
+ asyncio.run(main())
87
+ """
88
+
89
+ import ast
90
+ import asyncio
91
+ import os
92
+ import time
93
+ from dataclasses import dataclass
94
+ from typing import Type, TypeVar, List, Dict, Any, Callable
95
+ from queue import Queue
96
+ from threading import Lock
97
+
98
+ from veadk.utils.logger import get_logger
99
+ from veadk.utils.volcengine_sign import ve_request
100
+
101
+ logger = get_logger(__name__)
102
+
103
+ ak = os.getenv("VOLCENGINE_ACCESS_KEY")
104
+ sk = os.getenv("VOLCENGINE_SECRET_KEY")
105
+ tool_ids = ast.literal_eval(os.getenv("TOOL_MOBILE_USE_TOOL_ID", "[]"))
106
+ product_id = None
107
+ pod_ids = None
108
+
109
+ service_name = "ipaas"
110
+ region = "cn-north-1"
111
+ version = "2023-08-01"
112
+ host = "open.volcengineapi.com"
113
+
114
+ REQUIRED_ENV_VARS = [
115
+ "VOLCENGINE_ACCESS_KEY",
116
+ "VOLCENGINE_SECRET_KEY",
117
+ "TOOL_MOBILE_USE_TOOL_ID",
118
+ ]
119
+
120
+
121
+ class MobileUseToolError(Exception):
122
+ def __init__(self, msg: str):
123
+ self.msg = msg
124
+ logger.error(f"mobile use tool execute error :{msg}")
125
+
126
+
127
+ @dataclass
128
+ class ResponseMetadata:
129
+ RequestId: str
130
+ Action: str
131
+ Version: str
132
+ Service: str
133
+ Region: str
134
+
135
+
136
+ @dataclass
137
+ class RunAgentTaskResult:
138
+ RunId: str
139
+ RunName: str
140
+ ThreadId: str
141
+
142
+
143
+ @dataclass
144
+ class RunAgentTaskResponse:
145
+ ResponseMetadata: ResponseMetadata
146
+ Result: RunAgentTaskResult
147
+
148
+
149
+ @dataclass
150
+ class GetAgentResultResult:
151
+ IsSuccess: int
152
+ Content: str
153
+ StructOutput: str
154
+ ScreenShots: List[str]
155
+
156
+
157
+ @dataclass
158
+ class GetAgentResultResponse:
159
+ ResponseMetadata: ResponseMetadata
160
+ Result: GetAgentResultResult
161
+
162
+
163
+ @dataclass
164
+ class StepResult:
165
+ IsSuccess: bool
166
+ Result: str
167
+
168
+
169
+ @dataclass
170
+ class AgentRunCurrentStepInfo:
171
+ Action: str
172
+ Param: dict[str, str]
173
+ StepResult: StepResult
174
+
175
+
176
+ @dataclass
177
+ class ListAgentRunCurrentResponseResult:
178
+ RunId: str
179
+ ThreadId: str
180
+ Results: List[AgentRunCurrentStepInfo]
181
+
182
+
183
+ @dataclass
184
+ class ListAgentRunCurrentResponse:
185
+ Result: ListAgentRunCurrentResponseResult
186
+ ResponseMetadata: ResponseMetadata
187
+
188
+
189
+ T = TypeVar("T")
190
+
191
+
192
+ def _dict_to_dataclass(data: dict, cls: Type[T]) -> T:
193
+ field_values = {}
194
+ for field_name, field_type in cls.__dataclass_fields__.items():
195
+ field_value = data.get(field_name)
196
+ if field_value is None:
197
+ field_values[field_name] = None
198
+ continue
199
+
200
+ if hasattr(field_type.type, "__dataclass_fields__"):
201
+ field_values[field_name] = _dict_to_dataclass(field_value, field_type.type)
202
+ else:
203
+ field_values[field_name] = field_value
204
+ return cls(**field_values)
205
+
206
+
207
+ class PodPool:
208
+ def __init__(self, pod_ids: List[str]):
209
+ self.pod_ids = pod_ids
210
+ self.available_pods = Queue()
211
+ self.pod_lock = Lock()
212
+ self.task_map: Dict[str, str] = {}
213
+
214
+ for pid in pod_ids:
215
+ self.available_pods.put(str(pid))
216
+ logger.info(f"Pod pool initialized, available pods: {len(pod_ids)}")
217
+
218
+ def acquire_pod(self) -> Any | None:
219
+ try:
220
+ pid = self.available_pods.get(block=True)
221
+ with self.pod_lock:
222
+ self.task_map[pid] = "pending"
223
+ logger.debug(
224
+ f"Acquired pod: {pid}, available pods: {self.available_pods.qsize()}"
225
+ )
226
+ return pid
227
+ except Exception as e:
228
+ logger.warning(f"Pod acquisition timeout: {e}")
229
+ return None
230
+
231
+ def release_pod(self, pid: str) -> None:
232
+ with self.pod_lock:
233
+ if pid in self.task_map:
234
+ del self.task_map[pid]
235
+ self.available_pods.put(pid)
236
+ logger.debug(
237
+ f"Released pod: {pid}, available pods: {self.available_pods.qsize()}"
238
+ )
239
+
240
+ def get_pod_status(self, pid: str) -> str:
241
+ with self.pod_lock:
242
+ return self.task_map.get(pid, "available")
243
+
244
+ def get_available_count(self) -> int:
245
+ return self.available_pods.qsize()
246
+
247
+
248
+ def _run_agent_task(
249
+ system_prompt: str,
250
+ user_prompt: str,
251
+ pid: str,
252
+ max_step: int,
253
+ step_interval: int,
254
+ timeout: int,
255
+ ) -> RunAgentTaskResponse:
256
+ try:
257
+ run_task = ve_request(
258
+ request_body={
259
+ "RunName": "test-run",
260
+ "PodId": pid,
261
+ "ProductId": product_id,
262
+ "SystemPrompt": system_prompt,
263
+ "UserPrompt": user_prompt,
264
+ "MaxStep": max_step,
265
+ "StepInterval": step_interval,
266
+ "Timeout": timeout,
267
+ },
268
+ action="RunAgentTaskOneStep",
269
+ ak=ak,
270
+ sk=sk,
271
+ service=service_name,
272
+ version=version,
273
+ region=region,
274
+ content_type="application/json",
275
+ host=host,
276
+ )
277
+ except Exception as e:
278
+ raise MobileUseToolError(f"RunAgentTask invocation failed: {e}") from e
279
+
280
+ run_task_response = _dict_to_dataclass(run_task, RunAgentTaskResponse)
281
+ if (
282
+ not getattr(run_task_response, "Result", None)
283
+ or not run_task_response.Result
284
+ or not run_task_response.Result.RunId
285
+ ):
286
+ raise MobileUseToolError(f"RunAgentTask returned invalid result: {run_task}")
287
+ logger.debug(f"Agent run started: {run_task_response}")
288
+ return run_task_response
289
+
290
+
291
+ def _get_task_result(task_id: str) -> GetAgentResultResponse:
292
+ try:
293
+ task_result = ve_request(
294
+ request_body={},
295
+ query={
296
+ "RunId": task_id,
297
+ },
298
+ action="GetAgentResult",
299
+ ak=ak,
300
+ sk=sk,
301
+ service=service_name,
302
+ version=version,
303
+ region=region,
304
+ content_type="application/json",
305
+ host=host,
306
+ method="GET",
307
+ )
308
+ except Exception as e:
309
+ raise MobileUseToolError(f"GetAgentResult invocation failed: {e}") from e
310
+
311
+ result = _dict_to_dataclass(task_result, GetAgentResultResponse)
312
+ if not getattr(result, "Result", None):
313
+ raise MobileUseToolError(
314
+ f"GetAgentResult returned invalid result: {task_result}"
315
+ )
316
+ logger.debug(f"Fetched agent result: {result}")
317
+ return result
318
+
319
+
320
+ def _get_current_step(task_id: str) -> ListAgentRunCurrentResponse:
321
+ try:
322
+ current_step = ve_request(
323
+ request_body={},
324
+ query={"RunId": task_id},
325
+ action="ListAgentRunCurrentStep",
326
+ ak=ak,
327
+ sk=sk,
328
+ service=service_name,
329
+ version=version,
330
+ region=region,
331
+ content_type="application/json",
332
+ host=host,
333
+ method="GET",
334
+ )
335
+ except Exception as e:
336
+ raise MobileUseToolError(
337
+ f"ListAgentRunCurrentStep invocation failed: {e}"
338
+ ) from e
339
+
340
+ result = _dict_to_dataclass(current_step, ListAgentRunCurrentResponse)
341
+ if not getattr(result, "Result", None):
342
+ raise MobileUseToolError(
343
+ f"ListAgentRunCurrentStep returned invalid result: {current_step}"
344
+ )
345
+ logger.debug(f"Fetched agent current step: {result}")
346
+ return result
347
+
348
+
349
+ def _cancel_task(task_id: str) -> None:
350
+ try:
351
+ _ = ve_request(
352
+ request_body={},
353
+ query={"RunId": task_id},
354
+ action="CancelTask",
355
+ ak=ak,
356
+ sk=sk,
357
+ service=service_name,
358
+ version=version,
359
+ region=region,
360
+ content_type="application/json",
361
+ host=host,
362
+ method="POST",
363
+ )
364
+ logger.debug(f"Cancelled agent task: {task_id}")
365
+ except Exception as e:
366
+ raise MobileUseToolError(f"CancelAgentTask invocation failed: {e}") from e
367
+
368
+
369
+ def _require_env_vars() -> None:
370
+ missing = [name for name in REQUIRED_ENV_VARS if not os.getenv(name)]
371
+ if missing:
372
+ raise MobileUseToolError(
373
+ f"Missing required environment variables: {', '.join(missing)}"
374
+ )
375
+
376
+
377
+ def _get_product_and_pod():
378
+ if tool_ids is None or tool_ids.__len__() == 0:
379
+ raise MobileUseToolError("TOOL_MOBILE_USE_TOOL_ID is None")
380
+ global product_id
381
+ global pod_ids
382
+ if "-" in tool_ids[0]:
383
+ product_id = tool_ids[0].split("-")[0]
384
+ pod_ids = [tool_id.split("-")[1] for tool_id in tool_ids]
385
+ else:
386
+ raise MobileUseToolError(
387
+ "TOOL_MOBILE_USE_TOOL_ID is invalid, please check the tool id from https://console.volcengine.com/ACEP/"
388
+ )
389
+
390
+
391
+ def create_mobile_use_tool(
392
+ system_prompt: str,
393
+ timeout_seconds: int = 900,
394
+ max_step: int = 100,
395
+ step_interval_seconds: int = 1,
396
+ ):
397
+ """
398
+ Outer closure: initialize fixed configuration for the virtual mobile tool
399
+ (system prompt, timeout/polling parameters). Returns an inner tool
400
+ function that reuses the configuration to execute multiple user tasks.
401
+
402
+ Args:
403
+ system_prompt (str):
404
+ System-level instruction defining the agent role, behavior rules,
405
+ constraints, and security boundaries.
406
+ Example:
407
+ * "You are a mobile testing agent. Follow least-privilege principles and avoid unauthorized access."
408
+ max_step (int): Maximum execution steps per agent.
409
+ timeout_seconds (int):
410
+ Maximum wait time in seconds. Raises if not finished. Default: 600.
411
+ step_interval_seconds (int):
412
+ Status polling interval in seconds. Default: 1.
413
+
414
+ Returns:
415
+ Callable[[str], str]: Inner tool function that accepts user prompts to
416
+ perform tasks and returns results.
417
+ """
418
+ _require_env_vars()
419
+ _get_product_and_pod()
420
+ pod_pool = PodPool(pod_ids)
421
+
422
+ async def mobile_use_tool(user_prompts: List[str]) -> list[None]:
423
+ """
424
+ Virtual mobile execution tool. Use this when tasks require a mobile
425
+ device. The argument is a list of task prompts; each task is a string
426
+ describing the required operation.
427
+ If a task must run on a single device, pass a single-element list.
428
+ Example: ["Download and install WeChat"]
429
+ If a task can be split into subtasks across devices, pass each subtask
430
+ as an element.
431
+ Example: ["Search DeepSeek status", "Search Qianwen status"]
432
+
433
+ Args:
434
+ user_prompts: Task list; multiple sandbox devices exist in the system.
435
+
436
+ Returns:
437
+ List of results, aligned with the input order.
438
+ """
439
+ logger.info(
440
+ f"Processing task list, total {len(user_prompts)} tasks, available pods: {pod_pool.get_available_count()}"
441
+ )
442
+
443
+ results = [None] * len(user_prompts)
444
+ coroutines = []
445
+
446
+ def task_worker(index: int, prompt: str) -> Callable:
447
+ wait_start = time.time()
448
+
449
+ async def run():
450
+ nonlocal results
451
+ pod_id = None
452
+ try:
453
+ while True:
454
+ pod_id = pod_pool.acquire_pod()
455
+ if pod_id:
456
+ break
457
+ if time.time() - wait_start >= timeout_seconds:
458
+ raise MobileUseToolError(
459
+ f"Task {index} timed out acquiring pod after {timeout_seconds}s"
460
+ )
461
+ logger.debug(
462
+ f"Task {index} waiting for pod, available pods: {pod_pool.get_available_count()}"
463
+ )
464
+ await asyncio.sleep(1)
465
+
466
+ logger.info(
467
+ f"Task {index} assigned to pod: {pod_id}, starting: {prompt}"
468
+ )
469
+ task_response = _run_agent_task(
470
+ system_prompt,
471
+ prompt,
472
+ pod_id,
473
+ max_step,
474
+ step_interval_seconds,
475
+ timeout_seconds,
476
+ )
477
+ task_id = task_response.Result.RunId
478
+ pod_pool.task_map[pod_id] = task_id
479
+
480
+ while True:
481
+ result_response = _get_task_result(task_id)
482
+ if result_response.Result.IsSuccess == 1:
483
+ results[index] = (
484
+ f"task success: {result_response.Result.Content}\n"
485
+ )
486
+ logger.info(
487
+ f"Task {index} succeeded on pod: {pod_id}, result: {result_response.Result.Content}"
488
+ )
489
+ break
490
+ elif result_response.Result.IsSuccess == 2:
491
+ results[index] = (
492
+ f"task failed: {result_response.Result.Content}"
493
+ )
494
+ logger.error(f"Task {index} failed on pod: {pod_id}")
495
+ break
496
+
497
+ current_step = _get_current_step(task_id)
498
+ if current_step.Result.Results:
499
+ last_step = current_step.Result.Results[-1]
500
+ logger.debug(
501
+ f"Task {index}, thread_id={task_response.Result.ThreadId}, run_id={task_id}. Current step: {last_step['Action']}, status: {'success' if last_step['StepResult']['IsSuccess'] else 'failed'}"
502
+ )
503
+ await asyncio.sleep(5)
504
+
505
+ except Exception as e:
506
+ error_msg = f"Task {index} raised exception: {str(e)}"
507
+ results[index] = error_msg
508
+ logger.error(error_msg)
509
+ finally:
510
+ if pod_id:
511
+ _cancel_task(pod_pool.task_map[pod_id])
512
+ pod_pool.release_pod(pod_id)
513
+
514
+ return run
515
+
516
+ for i, prompt in enumerate(user_prompts):
517
+ coroutines.append(task_worker(i, prompt)())
518
+
519
+ # 并发执行所有任务
520
+ await asyncio.gather(*coroutines)
521
+ return results
522
+
523
+ return mobile_use_tool