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.
- {veadk_python-0.2.28/veadk_python.egg-info → veadk_python-0.2.29}/PKG-INFO +2 -1
- {veadk_python-0.2.28 → veadk_python-0.2.29}/pyproject.toml +2 -1
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/consts.py +1 -1
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/mcp_tool.py +2 -3
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/mcp_toolset.py +2 -3
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/utils.py +33 -0
- veadk_python-0.2.29/veadk/tools/builtin_tools/mobile_run.py +523 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/volcengine_sign.py +4 -7
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/version.py +1 -1
- {veadk_python-0.2.28 → veadk_python-0.2.29/veadk_python.egg-info}/PKG-INFO +2 -1
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/SOURCES.txt +1 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/requires.txt +1 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/LICENSE +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/README.md +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/setup.cfg +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_cloud.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_evaluator.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_knowledgebase.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_long_term_memory.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_misc.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_multiple_agents.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_runner.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_runtime_data_collecting.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_short_term_memory.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_tracing.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_a2a_middlewares.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_auth_config.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_function_tool.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_mcp_tool.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/tests/test_ve_identity_mcp_toolset.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/agent_card.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/remote_ve_agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/utils/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/utils/agent_to_a2a.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_a2a_server.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_agent_executor.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_middlewares.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/a2a/ve_task_store.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agent_builder.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/loop_agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/parallel_agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/agents/sequential_agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/base_auth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/ve_credential_service.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/apmplus_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/ark_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/base_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/cozeloop_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/opensearch_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/postgresql_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/prompt_pilot_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/speech_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/vesearch_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/auth/veauth/viking_mem0_veauth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_clean.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_create.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_deploy.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_eval.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_init.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_kb.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_pipeline.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_prompt.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_rl.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_update.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_uploadevalset.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/cli_web.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/README.md +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/arkworkspace.toml +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/data/demo_dataset.jsonl +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/job.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/job.yaml +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/random_reward.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/raw_async_veadk_rollout.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/plugins/test_utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/requirements.txt +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cli/templates/rl/ark/test_faas.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/cloud_agent_engine.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/cloud/cloud_app.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/config.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/auth_configs.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/database_configs.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/model_configs.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/tool_configs.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/configs/tracing_configs.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/adk_evaluator/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/adk_evaluator/adk_evaluator.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/base_evaluator.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/deepeval_evaluator/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/eval_set_file_loader.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/eval_set_recorder.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/types.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/evaluation/utils/prometheus.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/ve_apig.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_apig/ve_apig_utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_code_pipeline/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cozeloop/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cozeloop/ve_cozeloop.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cr/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_cr/ve_cr.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/cookiecutter.json +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +0 -0
- {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
- {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
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/ve_faas.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/ve_faas_utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/cookiecutter.json +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +0 -0
- {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
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_config.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_mixins.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/auth_processor.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/function_tool.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/identity_client.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/models.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_identity/token_manager.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_prompt_pilot/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tls/ve_tls.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_tos/ve_tos.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_viking_db_memory/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/base_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/in_memory_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/opensearch_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/redis_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/entry.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/knowledgebase/knowledgebase.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/base_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/in_memory_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/mem0_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/opensearch_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/redis_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/base_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/mysql_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/postgresql_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_backends/sqlite_backend.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/memory/short_term_memory_processor.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/processors/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/processors/base_run_processor.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/agent_default_prompt.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_evaluator.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_memory_processor.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/prompts/prompt_optimization.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/runner.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/agent_authorization.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/generate_image.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/image_edit.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/image_generate.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/lark.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/las.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/link_reader.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/llm_shield.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/load_knowledgebase.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/mcp_router.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/run_code.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/tts.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/vesearch.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/video_generate.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/web_scraper.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/builtin_tools/web_search.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/demo_tools.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/load_knowledgebase_tool.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/trusted_mcp_session_manager.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/mcp_tool/trusted_mcp_toolset.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/browser_sandbox.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/code_sandbox.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tools/sandbox/computer_sandbox.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/base_tracer.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/attributes.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/attributes/extractors/types.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/apmplus_exporter.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/base_exporter.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/cozeloop_exporter.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/inmemory_exporter.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/exporters/tls_exporter.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/opentelemetry_tracer.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/tracing/telemetry/telemetry.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/types.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/__init__.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/audio_manager.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/auth.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/logger.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/mcp_utils.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/misc.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk/utils/patches.py +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/dependency_links.txt +0 -0
- {veadk_python-0.2.28 → veadk_python-0.2.29}/veadk_python.egg-info/entry_points.txt +0 -0
- {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.
|
|
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.
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|