veadk-python 0.2.4__tar.gz → 0.2.5__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.

Potentially problematic release.


This version of veadk-python might be problematic. Click here for more details.

Files changed (146) hide show
  1. {veadk_python-0.2.4 → veadk_python-0.2.5}/PKG-INFO +1 -1
  2. {veadk_python-0.2.4 → veadk_python-0.2.5}/pyproject.toml +1 -1
  3. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_agent.py +7 -0
  4. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_cloud.py +6 -3
  5. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_runner.py +2 -2
  6. veadk_python-0.2.5/tests/test_tos.py +110 -0
  7. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/agent.py +28 -8
  8. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/cli_deploy.py +3 -1
  9. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cloud/cloud_app.py +21 -6
  10. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/consts.py +14 -1
  11. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/viking/viking_database.py +3 -3
  12. veadk_python-0.2.5/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  13. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +4 -1
  14. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +11 -1
  15. veadk_python-0.2.5/veadk/integrations/ve_tos/ve_tos.py +176 -0
  16. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/runner.py +107 -34
  17. veadk_python-0.2.5/veadk/tools/builtin_tools/image_edit.py +236 -0
  18. veadk_python-0.2.5/veadk/tools/builtin_tools/image_generate.py +236 -0
  19. veadk_python-0.2.5/veadk/tools/builtin_tools/video_generate.py +326 -0
  20. veadk_python-0.2.5/veadk/tools/sandbox/browser_sandbox.py +37 -0
  21. veadk_python-0.2.5/veadk/tools/sandbox/code_sandbox.py +40 -0
  22. veadk_python-0.2.4/veadk/tools/sandbox/code_sandbox.py → veadk_python-0.2.5/veadk/tools/sandbox/computer_sandbox.py +15 -11
  23. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/base_tracer.py +0 -19
  24. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +65 -6
  25. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +20 -14
  26. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/inmemory_exporter.py +3 -0
  27. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/opentelemetry_tracer.py +4 -1
  28. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/telemetry.py +113 -24
  29. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/misc.py +40 -0
  30. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/version.py +1 -1
  31. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk_python.egg-info/PKG-INFO +1 -1
  32. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk_python.egg-info/SOURCES.txt +6 -0
  33. veadk_python-0.2.4/veadk/tools/sandbox/browser_sandbox.py +0 -27
  34. veadk_python-0.2.4/veadk/tools/sandbox/computer_sandbox.py +0 -27
  35. {veadk_python-0.2.4 → veadk_python-0.2.5}/LICENSE +0 -0
  36. {veadk_python-0.2.4 → veadk_python-0.2.5}/README.md +0 -0
  37. {veadk_python-0.2.4 → veadk_python-0.2.5}/setup.cfg +0 -0
  38. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_agent_card.py +0 -0
  39. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_evaluator.py +0 -0
  40. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_knowledgebase.py +0 -0
  41. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_long_term_memory.py +0 -0
  42. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_multiple_agents.py +0 -0
  43. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_runtime_data_collecting.py +0 -0
  44. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_short_term_memory.py +0 -0
  45. {veadk_python-0.2.4 → veadk_python-0.2.5}/tests/test_tracing.py +0 -0
  46. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/__init__.py +0 -0
  47. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/__init__.py +0 -0
  48. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/agent_card.py +0 -0
  49. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/remote_ve_agent.py +0 -0
  50. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/ve_a2a_server.py +0 -0
  51. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/ve_agent_executor.py +0 -0
  52. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/a2a/ve_task_store.py +0 -0
  53. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/agents/loop_agent.py +0 -0
  54. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/agents/parallel_agent.py +0 -0
  55. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/agents/sequential_agent.py +0 -0
  56. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/__init__.py +0 -0
  57. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/cli.py +0 -0
  58. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/cli_init.py +0 -0
  59. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/cli_prompt.py +0 -0
  60. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cli/cli_web.py +0 -0
  61. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cloud/__init__.py +0 -0
  62. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/cloud/cloud_agent_engine.py +0 -0
  63. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/config.py +0 -0
  64. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/__init__.py +0 -0
  65. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/base_database.py +0 -0
  66. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/database_adapter.py +0 -0
  67. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/database_factory.py +0 -0
  68. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/kv/__init__.py +0 -0
  69. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/kv/redis_database.py +0 -0
  70. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/local_database.py +0 -0
  71. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/relational/__init__.py +0 -0
  72. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/relational/mysql_database.py +0 -0
  73. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/vector/__init__.py +0 -0
  74. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/vector/opensearch_vector_database.py +0 -0
  75. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/vector/type.py +0 -0
  76. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/viking/__init__.py +0 -0
  77. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/database/viking/viking_memory_db.py +0 -0
  78. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/__init__.py +0 -0
  79. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/adk_evaluator/__init__.py +0 -0
  80. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/adk_evaluator/adk_evaluator.py +0 -0
  81. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/base_evaluator.py +0 -0
  82. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/deepeval_evaluator/__init__.py +0 -0
  83. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +0 -0
  84. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/eval_set_file_loader.py +0 -0
  85. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/eval_set_recorder.py +0 -0
  86. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/types.py +0 -0
  87. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/evaluation/utils/prometheus.py +0 -0
  88. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_apig/__init__.py +0 -0
  89. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_apig/ve_apig.py +0 -0
  90. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_apig/ve_apig_utils.py +0 -0
  91. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/__init__.py +0 -0
  92. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/cookiecutter.json +0 -0
  93. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +0 -0
  94. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +0 -0
  95. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +0 -0
  96. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +0 -0
  97. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +0 -0
  98. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +0 -0
  99. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name|replace('-', '_') }}/__init__.py +0 -0
  100. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name|replace('-', '_') }}/agent.py +0 -0
  101. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/ve_faas.py +0 -0
  102. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_faas/ve_faas_utils.py +0 -0
  103. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_prompt_pilot/__init__.py +0 -0
  104. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +0 -0
  105. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/knowledgebase/__init__.py +0 -0
  106. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/knowledgebase/knowledgebase.py +0 -0
  107. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/memory/__init__.py +0 -0
  108. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/memory/long_term_memory.py +0 -0
  109. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/memory/short_term_memory.py +0 -0
  110. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/memory/short_term_memory_processor.py +0 -0
  111. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/prompts/__init__.py +0 -0
  112. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/prompts/agent_default_prompt.py +0 -0
  113. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/prompts/prompt_evaluator.py +0 -0
  114. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/prompts/prompt_memory_processor.py +0 -0
  115. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/prompts/prompt_optimization.py +0 -0
  116. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/__init__.py +0 -0
  117. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/__init__.py +0 -0
  118. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/lark.py +0 -0
  119. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/las.py +0 -0
  120. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/mcp_router.py +0 -0
  121. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/vesearch.py +0 -0
  122. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/web_scraper.py +0 -0
  123. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/builtin_tools/web_search.py +0 -0
  124. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/demo_tools.py +0 -0
  125. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/load_knowledgebase_tool.py +0 -0
  126. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tools/sandbox/__init__.py +0 -0
  127. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/__init__.py +0 -0
  128. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/__init__.py +0 -0
  129. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/attributes/attributes.py +0 -0
  130. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +0 -0
  131. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/attributes/extractors/types.py +0 -0
  132. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/__init__.py +0 -0
  133. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/apmplus_exporter.py +0 -0
  134. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/base_exporter.py +0 -0
  135. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/cozeloop_exporter.py +0 -0
  136. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/tracing/telemetry/exporters/tls_exporter.py +0 -0
  137. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/types.py +0 -0
  138. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/__init__.py +0 -0
  139. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/logger.py +0 -0
  140. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/mcp_utils.py +0 -0
  141. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/patches.py +0 -0
  142. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk/utils/volcengine_sign.py +0 -0
  143. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk_python.egg-info/dependency_links.txt +0 -0
  144. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk_python.egg-info/entry_points.txt +0 -0
  145. {veadk_python-0.2.4 → veadk_python-0.2.5}/veadk_python.egg-info/requires.txt +0 -0
  146. {veadk_python-0.2.4 → veadk_python-0.2.5}/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.4
3
+ Version: 0.2.5
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "veadk-python"
3
- version = "0.2.4"
3
+ version = "0.2.5"
4
4
  description = "Volcengine agent development kit, integrations with Volcengine cloud services."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -15,6 +15,7 @@
15
15
  from google.adk.tools import load_memory
16
16
 
17
17
  from veadk import Agent
18
+ from veadk.consts import DEFAULT_MODEL_EXTRA_HEADERS
18
19
  from veadk.knowledgebase import KnowledgeBase
19
20
  from veadk.memory.long_term_memory import LongTermMemory
20
21
  from veadk.tools import load_knowledgebase_tool
@@ -26,11 +27,14 @@ def test_agent():
26
27
  long_term_memory = LongTermMemory(backend="local")
27
28
  tracer = OpentelemetryTracer()
28
29
 
30
+ model_extra_headers = {"test-header": "test-value"}
31
+
29
32
  agent = Agent(
30
33
  model_name="test_model_name",
31
34
  model_provider="test_model_provider",
32
35
  model_api_key="test_model_api_key",
33
36
  model_api_base="test_model_api_base",
37
+ model_extra_headers=model_extra_headers,
34
38
  tools=[],
35
39
  sub_agents=[],
36
40
  knowledgebase=knowledgebase,
@@ -39,7 +43,10 @@ def test_agent():
39
43
  serve_url="",
40
44
  )
41
45
 
46
+ model_extra_headers |= DEFAULT_MODEL_EXTRA_HEADERS
47
+
42
48
  assert agent.model.model == f"{agent.model_provider}/{agent.model_name}"
49
+ assert agent.model_extra_headers == model_extra_headers
43
50
 
44
51
  assert agent.knowledgebase == knowledgebase
45
52
  assert agent.knowledgebase.backend == "local"
@@ -115,9 +115,12 @@ async def test_cloud():
115
115
  mock_vefaas_client = Mock()
116
116
  mock_vefaas_in_app.return_value = mock_vefaas_client
117
117
  mock_vefaas_client.delete.return_value = None
118
-
119
- cloud_app.delete_self()
120
- mock_vefaas_client.delete.assert_called_with("app-123")
118
+ with patch.object(
119
+ cloud_app, "_get_vefaas_application_id_by_name"
120
+ ) as mock_get_id_by_name:
121
+ mock_get_id_by_name.return_value = None
122
+ cloud_app.delete_self()
123
+ mock_vefaas_client.delete.assert_called_with("app-123")
121
124
 
122
125
  # Verify all mocks were called as expected
123
126
  mock_vefaas_service.deploy.assert_called_once()
@@ -28,7 +28,7 @@ def _test_convert_messages(runner):
28
28
  role="user",
29
29
  )
30
30
  ]
31
- actual_message = runner._convert_messages(message)
31
+ actual_message = runner._convert_messages(message, session_id="test_session_id")
32
32
  assert actual_message == expected_message
33
33
 
34
34
  message = ["test message 1", "test message 2"]
@@ -42,7 +42,7 @@ def _test_convert_messages(runner):
42
42
  role="user",
43
43
  ),
44
44
  ]
45
- actual_message = runner._convert_messages(message)
45
+ actual_message = runner._convert_messages(message, session_id="test_session_id")
46
46
  assert actual_message == expected_message
47
47
 
48
48
 
@@ -0,0 +1,110 @@
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
+ import pytest
16
+ from unittest import mock
17
+ import veadk.integrations.ve_tos.ve_tos as tos_mod
18
+
19
+ # 使用 pytest-asyncio
20
+ pytest_plugins = ("pytest_asyncio",)
21
+
22
+
23
+ @pytest.fixture
24
+ def mock_client(monkeypatch):
25
+ fake_client = mock.Mock()
26
+
27
+ monkeypatch.setenv("DATABASE_TOS_REGION", "test-region")
28
+ monkeypatch.setenv("VOLCENGINE_ACCESS_KEY", "test-access-key")
29
+ monkeypatch.setenv("VOLCENGINE_SECRET_KEY", "test-secret-key")
30
+ monkeypatch.setenv("DATABASE_TOS_BUCKET", "test-bucket")
31
+
32
+ monkeypatch.setattr(tos_mod.tos, "TosClientV2", lambda *a, **k: fake_client)
33
+
34
+ class FakeExceptions:
35
+ class TosServerError(Exception):
36
+ def __init__(self, msg):
37
+ super().__init__(msg)
38
+ self.status_code = None
39
+
40
+ monkeypatch.setattr(tos_mod.tos, "exceptions", FakeExceptions)
41
+ monkeypatch.setattr(
42
+ tos_mod.tos,
43
+ "StorageClassType",
44
+ type("S", (), {"Storage_Class_Standard": "STANDARD"}),
45
+ )
46
+ monkeypatch.setattr(
47
+ tos_mod.tos, "ACLType", type("A", (), {"ACL_Private": "private"})
48
+ )
49
+
50
+ return fake_client
51
+
52
+
53
+ @pytest.fixture
54
+ def tos_client(mock_client):
55
+ return tos_mod.VeTOS()
56
+
57
+
58
+ def test_create_bucket_exists(tos_client, mock_client):
59
+ mock_client.head_bucket.return_value = None # head_bucket 正常返回表示存在
60
+ result = tos_client.create_bucket()
61
+ assert result is True
62
+ mock_client.create_bucket.assert_not_called()
63
+
64
+
65
+ def test_create_bucket_not_exists(tos_client, mock_client):
66
+ exc = tos_mod.tos.exceptions.TosServerError("not found")
67
+ exc.status_code = 404
68
+ mock_client.head_bucket.side_effect = exc
69
+
70
+ result = tos_client.create_bucket()
71
+ assert result is True
72
+ mock_client.create_bucket.assert_called_once()
73
+
74
+
75
+ @pytest.mark.asyncio
76
+ async def test_upload_bytes_success(tos_client, mock_client):
77
+ mock_client.head_bucket.return_value = True
78
+ data = b"hello world"
79
+
80
+ result = await tos_client.upload("obj-key", data)
81
+ assert result is True
82
+ mock_client.put_object.assert_called_once()
83
+ mock_client.close.assert_called_once()
84
+
85
+
86
+ @pytest.mark.asyncio
87
+ async def test_upload_file_success(tmp_path, tos_client, mock_client):
88
+ mock_client.head_bucket.return_value = True
89
+ file_path = tmp_path / "file.txt"
90
+ file_path.write_text("hello file")
91
+
92
+ result = await tos_client.upload("obj-key", str(file_path))
93
+ assert result is True
94
+ mock_client.put_object_from_file.assert_called_once()
95
+ mock_client.close.assert_called_once()
96
+
97
+
98
+ def test_download_success(tmp_path, tos_client, mock_client):
99
+ save_path = tmp_path / "out.txt"
100
+ mock_client.get_object.return_value = [b"abc", b"def"]
101
+
102
+ result = tos_client.download("obj-key", str(save_path))
103
+ assert result is True
104
+ assert save_path.read_bytes() == b"abcdef"
105
+
106
+
107
+ def test_download_fail(tos_client, mock_client):
108
+ mock_client.get_object.side_effect = Exception("boom")
109
+ result = tos_client.download("obj-key", "somewhere.txt")
110
+ assert result is False
@@ -28,9 +28,10 @@ from typing_extensions import Any
28
28
 
29
29
  from veadk.config import getenv
30
30
  from veadk.consts import (
31
- DEFALUT_MODEL_AGENT_PROVIDER,
31
+ DEFAULT_MODEL_AGENT_PROVIDER,
32
32
  DEFAULT_MODEL_AGENT_API_BASE,
33
33
  DEFAULT_MODEL_AGENT_NAME,
34
+ DEFAULT_MODEL_EXTRA_HEADERS,
34
35
  )
35
36
  from veadk.evaluation import EvalSetRecorder
36
37
  from veadk.knowledgebase import KnowledgeBase
@@ -64,7 +65,7 @@ class Agent(LlmAgent):
64
65
  model_name: str = getenv("MODEL_AGENT_NAME", DEFAULT_MODEL_AGENT_NAME)
65
66
  """The name of the model for agent running."""
66
67
 
67
- model_provider: str = getenv("MODEL_AGENT_PROVIDER", DEFALUT_MODEL_AGENT_PROVIDER)
68
+ model_provider: str = getenv("MODEL_AGENT_PROVIDER", DEFAULT_MODEL_AGENT_PROVIDER)
68
69
  """The provider of the model for agent running."""
69
70
 
70
71
  model_api_base: str = getenv("MODEL_AGENT_API_BASE", DEFAULT_MODEL_AGENT_API_BASE)
@@ -73,6 +74,9 @@ class Agent(LlmAgent):
73
74
  model_api_key: str = Field(default_factory=lambda: getenv("MODEL_AGENT_API_KEY"))
74
75
  """The api key of the model for agent running."""
75
76
 
77
+ model_extra_config: dict = Field(default_factory=dict)
78
+ """The extra config to include in the model requests."""
79
+
76
80
  tools: list[ToolUnion] = []
77
81
  """The tools provided to agent."""
78
82
 
@@ -96,11 +100,27 @@ class Agent(LlmAgent):
96
100
 
97
101
  def model_post_init(self, __context: Any) -> None:
98
102
  super().model_post_init(None) # for sub_agents init
99
- self.model = LiteLlm(
100
- model=f"{self.model_provider}/{self.model_name}",
101
- api_key=self.model_api_key,
102
- api_base=self.model_api_base,
103
- )
103
+
104
+ # add model request source (veadk) in extra headers
105
+ if self.model_extra_config and "extra_headers" in self.model_extra_config:
106
+ self.model_extra_config["extra_headers"] |= DEFAULT_MODEL_EXTRA_HEADERS
107
+ else:
108
+ self.model_extra_config["extra_headers"] = DEFAULT_MODEL_EXTRA_HEADERS
109
+
110
+ if not self.model:
111
+ self.model = LiteLlm(
112
+ model=f"{self.model_provider}/{self.model_name}",
113
+ api_key=self.model_api_key,
114
+ api_base=self.model_api_base,
115
+ **self.model_extra_config,
116
+ )
117
+ logger.debug(
118
+ f"LiteLLM client created with config: {self.model_extra_config}"
119
+ )
120
+ else:
121
+ logger.warning(
122
+ "You are trying to use your own LiteLLM client, some default request headers may be missing."
123
+ )
104
124
 
105
125
  if self.knowledgebase:
106
126
  from veadk.tools import load_knowledgebase_tool
@@ -117,7 +137,7 @@ class Agent(LlmAgent):
117
137
 
118
138
  logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
119
139
  logger.debug(
120
- f"Agent: {self.model_dump(include={'name', 'model_name', 'model_api_base', 'tools', 'serve_url'})}"
140
+ f"Agent: {self.model_dump(include={'name', 'model_name', 'model_api_base', 'tools'})}"
121
141
  )
122
142
 
123
143
  async def _run(
@@ -29,7 +29,9 @@ TEMP_PATH = "/tmp"
29
29
  default=None,
30
30
  help="Volcengine secret key",
31
31
  )
32
- @click.option("--vefaas-app-name", help="Expected Volcengine FaaS application name")
32
+ @click.option(
33
+ "--vefaas-app-name", required=True, help="Expected Volcengine FaaS application name"
34
+ )
33
35
  @click.option(
34
36
  "--veapig-instance-name", default="", help="Expected Volcengine APIG instance name"
35
37
  )
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import json
16
+ import time
16
17
  from typing import Any
17
18
  from uuid import uuid4
18
19
 
@@ -60,9 +61,11 @@ class CloudApp:
60
61
  if not vefaas_endpoint:
61
62
  self.vefaas_endpoint = self._get_vefaas_endpoint()
62
63
 
63
- if not self.vefaas_endpoint.startswith(
64
- "http"
65
- ) and not self.vefaas_endpoint.startswith("https"):
64
+ if (
65
+ self.vefaas_endpoint
66
+ and not self.vefaas_endpoint.startswith("http")
67
+ and not self.vefaas_endpoint.startswith("https")
68
+ ):
66
69
  raise ValueError(
67
70
  f"Invalid endpoint: {vefaas_endpoint}. The endpoint must start with `http` or `https`."
68
71
  )
@@ -92,12 +95,13 @@ class CloudApp:
92
95
  raise ValueError(
93
96
  f"VeFaaS CloudAPP with application_id `{self.vefaas_application_id}` or application_name `{self.vefaas_application_name}` not found."
94
97
  )
95
- cloud_resource = json.loads(app["CloudResource"])
96
98
 
97
99
  try:
100
+ cloud_resource = json.loads(app["CloudResource"])
98
101
  vefaas_endpoint = cloud_resource["framework"]["url"]["system_url"]
99
102
  except Exception as e:
100
- raise ValueError(f"VeFaaS cloudAPP could not get endpoint. Error: {e}")
103
+ logger.warning(f"VeFaaS cloudAPP could not get endpoint. Error: {e}")
104
+ vefaas_endpoint = ""
101
105
  return vefaas_endpoint
102
106
 
103
107
  def _get_vefaas_application_id_by_name(self) -> str:
@@ -167,7 +171,18 @@ class CloudApp:
167
171
 
168
172
  vefaas_client = VeFaaS(access_key=volcengine_ak, secret_key=volcengine_sk)
169
173
  vefaas_client.delete(self.vefaas_application_id)
170
- print(f"Cloud app {self.vefaas_application_id} is deleting...")
174
+ print(
175
+ f"Cloud app {self.vefaas_application_id} delete request has been sent to VeFaaS"
176
+ )
177
+ while True:
178
+ try:
179
+ id = self._get_vefaas_application_id_by_name()
180
+ if not id:
181
+ break
182
+ time.sleep(3)
183
+ except Exception as _:
184
+ break
185
+ print("Delete application done.")
171
186
 
172
187
  async def message_send(
173
188
  self, message: str, session_id: str, user_id: str, timeout: float = 600.0
@@ -12,6 +12,19 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from veadk.version import VERSION
16
+
15
17
  DEFAULT_MODEL_AGENT_NAME = "doubao-seed-1-6-250615"
16
- DEFALUT_MODEL_AGENT_PROVIDER = "openai"
18
+ DEFAULT_MODEL_AGENT_PROVIDER = "openai"
17
19
  DEFAULT_MODEL_AGENT_API_BASE = "https://ark.cn-beijing.volces.com/api/v3/"
20
+ DEFAULT_MODEL_EXTRA_HEADERS = {"veadk-source": "veadk", "veadk-version": VERSION}
21
+
22
+ DEFAULT_APMPLUS_OTEL_EXPORTER_ENDPOINT = "http://apmplus-cn-beijing.volces.com:4317"
23
+ DEFAULT_APMPLUS_OTEL_EXPORTER_SERVICE_NAME = "veadk_tracing"
24
+
25
+ DEFAULT_COZELOOP_OTEL_EXPORTER_ENDPOINT = (
26
+ "https://api.coze.cn/v1/loop/opentelemetry/v1/traces"
27
+ )
28
+
29
+ DEFAULT_TLS_OTEL_EXPORTER_ENDPOINT = "https://tls-cn-beijing.volces.com:4318/v1/traces"
30
+ DEFAULT_TLS_OTEL_EXPORTER_REGION = "cn-beijing"
@@ -387,9 +387,9 @@ class VikingDatabase(BaseModel, BaseDatabase):
387
387
  logger.error(f"Error in list_collections: {result['message']}")
388
388
  raise ValueError(f"Error in list_collections: {result['message']}")
389
389
 
390
- collections = result["data"]["collection_list"]
391
- if not collections:
392
- raise ValueError(f"No collections found in project {self.config.project}.")
390
+ collections = result["data"].get("collection_list", [])
391
+ if len(collections) == 0:
392
+ return False
393
393
 
394
394
  collection_list = set()
395
395
 
@@ -0,0 +1,23 @@
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
+ from veadk.cloud.cloud_app import CloudApp
16
+
17
+ def main() -> None:
18
+ cloud_app = CloudApp(vefaas_application_name="{{cookiecutter.vefaas_application_name}}")
19
+ cloud_app.delete_self()
20
+
21
+
22
+ if __name__ == "__main__":
23
+ main()
@@ -26,6 +26,7 @@ from fastmcp import FastMCP
26
26
  from starlette.routing import Route
27
27
 
28
28
  from google.adk.a2a.utils.agent_card_builder import AgentCardBuilder
29
+ from a2a.types import AgentProvider
29
30
 
30
31
  from veadk.a2a.ve_a2a_server import init_app
31
32
  from veadk.runner import Runner
@@ -46,7 +47,9 @@ app_name = agent_run_config.app_name
46
47
  agent = agent_run_config.agent
47
48
  short_term_memory = agent_run_config.short_term_memory
48
49
 
49
- agent_card_builder = AgentCardBuilder(agent=agent)
50
+ VEFAAS_REGION = os.getenv("APP_REGION", "cn-beijing")
51
+ VEFAAS_FUNC_ID = os.getenv("_FAAS_FUNC_ID", "")
52
+ agent_card_builder = AgentCardBuilder(agent=agent, provider=AgentProvider(organization="Volcengine Agent Development Kit (VeADK)", url=f"https://console.volcengine.com/vefaas/region:vefaas+{VEFAAS_REGION}/function/detail/{VEFAAS_FUNC_ID}"))
50
53
 
51
54
 
52
55
  def load_tracer() -> None:
@@ -34,7 +34,17 @@ while [[ $# -gt 0 ]]; do
34
34
  done
35
35
 
36
36
  # in case of deployment deps not installed in user's requirements.txt
37
- python3 -m pip install uvicorn[standard] fastapi
37
+ if pip list | grep -q "^fastapi \|^uvicorn "; then
38
+ echo "fastapi and uvicorn already installed"
39
+ else
40
+ python3 -m pip install uvicorn[standard] fastapi
41
+ fi
42
+
43
+ # Check if MODEL_AGENT_API_KEY is set
44
+ if [ -z "$MODEL_AGENT_API_KEY" ]; then
45
+ echo "MODEL_AGENT_API_KEY is not set. Please set it in your environment variables."
46
+ exit 1
47
+ fi
38
48
 
39
49
  USE_ADK_WEB=${USE_ADK_WEB:-False}
40
50
 
@@ -0,0 +1,176 @@
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
+ import os
16
+ from veadk.config import getenv
17
+ from veadk.utils.logger import get_logger
18
+ import tos
19
+ import asyncio
20
+ from typing import Union
21
+ from pydantic import BaseModel, Field
22
+ from typing import Any
23
+ from urllib.parse import urlparse
24
+ from datetime import datetime
25
+
26
+ logger = get_logger(__name__)
27
+
28
+
29
+ class TOSConfig(BaseModel):
30
+ region: str = Field(
31
+ default_factory=lambda: getenv("DATABASE_TOS_REGION"),
32
+ description="TOS region",
33
+ )
34
+ ak: str = Field(
35
+ default_factory=lambda: getenv("VOLCENGINE_ACCESS_KEY"),
36
+ description="Volcengine access key",
37
+ )
38
+ sk: str = Field(
39
+ default_factory=lambda: getenv("VOLCENGINE_SECRET_KEY"),
40
+ description="Volcengine secret key",
41
+ )
42
+ bucket_name: str = Field(
43
+ default_factory=lambda: getenv("DATABASE_TOS_BUCKET"),
44
+ description="TOS bucket name",
45
+ )
46
+
47
+
48
+ class VeTOS(BaseModel):
49
+ config: TOSConfig = Field(default_factory=TOSConfig)
50
+
51
+ def model_post_init(self, __context: Any) -> None:
52
+ try:
53
+ self._client = tos.TosClientV2(
54
+ self.config.ak,
55
+ self.config.sk,
56
+ endpoint=f"tos-{self.config.region}.volces.com",
57
+ region=self.config.region,
58
+ )
59
+ logger.info("Connected to TOS successfully.")
60
+ except Exception as e:
61
+ logger.error(f"Client initialization failed:{e}")
62
+ return None
63
+
64
+ def create_bucket(self) -> bool:
65
+ """If the bucket does not exist, create it"""
66
+ try:
67
+ self._client.head_bucket(self.config.bucket_name)
68
+ logger.info(f"Bucket {self.config.bucket_name} already exists")
69
+ return True
70
+ except tos.exceptions.TosServerError as e:
71
+ if e.status_code == 404:
72
+ self._client.create_bucket(
73
+ bucket=self.config.bucket_name,
74
+ storage_class=tos.StorageClassType.Storage_Class_Standard,
75
+ acl=tos.ACLType.ACL_Private,
76
+ )
77
+ logger.info(f"Bucket {self.config.bucket_name} created successfully")
78
+ return True
79
+ except Exception as e:
80
+ logger.error(f"Bucket creation failed: {str(e)}")
81
+ return False
82
+
83
+ def build_tos_url(
84
+ self, user_id: str, app_name: str, session_id: str, data_path: str
85
+ ) -> tuple[str, str]:
86
+ """generate TOS object key"""
87
+ parsed_url = urlparse(data_path)
88
+
89
+ if parsed_url.scheme and parsed_url.scheme in ("http", "https", "ftp", "ftps"):
90
+ file_name = os.path.basename(parsed_url.path)
91
+ else:
92
+ file_name = os.path.basename(data_path)
93
+
94
+ timestamp: str = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
95
+ object_key: str = f"{app_name}-{user_id}-{session_id}/{timestamp}-{file_name}"
96
+ tos_url: str = f"https://{self.config.bucket_name}.tos-{self.config.region}.volces.com/{object_key}"
97
+
98
+ return object_key, tos_url
99
+
100
+ def upload(
101
+ self,
102
+ object_key: str,
103
+ data: Union[str, bytes],
104
+ ):
105
+ if isinstance(data, str):
106
+ data_type = "file"
107
+ elif isinstance(data, bytes):
108
+ data_type = "bytes"
109
+ else:
110
+ error_msg = f"Upload failed: data type error. Only str (file path) and bytes are supported, got {type(data)}"
111
+ logger.error(error_msg)
112
+ raise ValueError(error_msg)
113
+ if data_type == "file":
114
+ return asyncio.to_thread(self._do_upload_file, object_key, data)
115
+ elif data_type == "bytes":
116
+ return asyncio.to_thread(self._do_upload_bytes, object_key, data)
117
+
118
+ def _do_upload_bytes(self, object_key: str, bytes: bytes) -> bool:
119
+ try:
120
+ if not self._client:
121
+ return False
122
+ if not self.create_bucket():
123
+ return False
124
+ self._client.put_object(
125
+ bucket=self.config.bucket_name, key=object_key, content=bytes
126
+ )
127
+ logger.debug(f"Upload success, object_key: {object_key}")
128
+ self._close()
129
+ return True
130
+ except Exception as e:
131
+ logger.error(f"Upload failed: {e}")
132
+ self._close()
133
+ return False
134
+
135
+ def _do_upload_file(self, object_key: str, file_path: str) -> bool:
136
+ try:
137
+ if not self._client:
138
+ return False
139
+ if not self.create_bucket():
140
+ return False
141
+
142
+ self._client.put_object_from_file(
143
+ bucket=self.config.bucket_name, key=object_key, file_path=file_path
144
+ )
145
+ self._close()
146
+ logger.debug(f"Upload success, object_key: {object_key}")
147
+ return True
148
+ except Exception as e:
149
+ logger.error(f"Upload failed: {e}")
150
+ self._close()
151
+ return False
152
+
153
+ def download(self, object_key: str, save_path: str) -> bool:
154
+ """download image from TOS"""
155
+ try:
156
+ object_stream = self._client.get_object(self.config.bucket_name, object_key)
157
+
158
+ save_dir = os.path.dirname(save_path)
159
+ if save_dir and not os.path.exists(save_dir):
160
+ os.makedirs(save_dir, exist_ok=True)
161
+
162
+ with open(save_path, "wb") as f:
163
+ for chunk in object_stream:
164
+ f.write(chunk)
165
+
166
+ logger.debug(f"Image download success, saved to: {save_path}")
167
+ return True
168
+
169
+ except Exception as e:
170
+ logger.error(f"Image download failed: {str(e)}")
171
+
172
+ return False
173
+
174
+ def _close(self):
175
+ if self._client:
176
+ self._client.close()