veadk-python 0.2.27__py3-none-any.whl

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 (218) hide show
  1. veadk/__init__.py +37 -0
  2. veadk/a2a/__init__.py +13 -0
  3. veadk/a2a/agent_card.py +45 -0
  4. veadk/a2a/remote_ve_agent.py +390 -0
  5. veadk/a2a/utils/__init__.py +13 -0
  6. veadk/a2a/utils/agent_to_a2a.py +170 -0
  7. veadk/a2a/ve_a2a_server.py +93 -0
  8. veadk/a2a/ve_agent_executor.py +78 -0
  9. veadk/a2a/ve_middlewares.py +313 -0
  10. veadk/a2a/ve_task_store.py +37 -0
  11. veadk/agent.py +402 -0
  12. veadk/agent_builder.py +93 -0
  13. veadk/agents/loop_agent.py +68 -0
  14. veadk/agents/parallel_agent.py +72 -0
  15. veadk/agents/sequential_agent.py +64 -0
  16. veadk/auth/__init__.py +13 -0
  17. veadk/auth/base_auth.py +22 -0
  18. veadk/auth/ve_credential_service.py +203 -0
  19. veadk/auth/veauth/__init__.py +13 -0
  20. veadk/auth/veauth/apmplus_veauth.py +58 -0
  21. veadk/auth/veauth/ark_veauth.py +75 -0
  22. veadk/auth/veauth/base_veauth.py +50 -0
  23. veadk/auth/veauth/cozeloop_veauth.py +13 -0
  24. veadk/auth/veauth/opensearch_veauth.py +75 -0
  25. veadk/auth/veauth/postgresql_veauth.py +75 -0
  26. veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
  27. veadk/auth/veauth/speech_veauth.py +54 -0
  28. veadk/auth/veauth/utils.py +69 -0
  29. veadk/auth/veauth/vesearch_veauth.py +62 -0
  30. veadk/auth/veauth/viking_mem0_veauth.py +91 -0
  31. veadk/cli/__init__.py +13 -0
  32. veadk/cli/cli.py +58 -0
  33. veadk/cli/cli_clean.py +87 -0
  34. veadk/cli/cli_create.py +163 -0
  35. veadk/cli/cli_deploy.py +233 -0
  36. veadk/cli/cli_eval.py +215 -0
  37. veadk/cli/cli_init.py +214 -0
  38. veadk/cli/cli_kb.py +110 -0
  39. veadk/cli/cli_pipeline.py +285 -0
  40. veadk/cli/cli_prompt.py +86 -0
  41. veadk/cli/cli_update.py +106 -0
  42. veadk/cli/cli_uploadevalset.py +139 -0
  43. veadk/cli/cli_web.py +143 -0
  44. veadk/cloud/__init__.py +13 -0
  45. veadk/cloud/cloud_agent_engine.py +485 -0
  46. veadk/cloud/cloud_app.py +475 -0
  47. veadk/config.py +115 -0
  48. veadk/configs/__init__.py +13 -0
  49. veadk/configs/auth_configs.py +133 -0
  50. veadk/configs/database_configs.py +132 -0
  51. veadk/configs/model_configs.py +78 -0
  52. veadk/configs/tool_configs.py +54 -0
  53. veadk/configs/tracing_configs.py +110 -0
  54. veadk/consts.py +74 -0
  55. veadk/evaluation/__init__.py +17 -0
  56. veadk/evaluation/adk_evaluator/__init__.py +17 -0
  57. veadk/evaluation/adk_evaluator/adk_evaluator.py +302 -0
  58. veadk/evaluation/base_evaluator.py +642 -0
  59. veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
  60. veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +339 -0
  61. veadk/evaluation/eval_set_file_loader.py +48 -0
  62. veadk/evaluation/eval_set_recorder.py +146 -0
  63. veadk/evaluation/types.py +65 -0
  64. veadk/evaluation/utils/prometheus.py +196 -0
  65. veadk/integrations/__init__.py +13 -0
  66. veadk/integrations/ve_apig/__init__.py +13 -0
  67. veadk/integrations/ve_apig/ve_apig.py +349 -0
  68. veadk/integrations/ve_apig/ve_apig_utils.py +332 -0
  69. veadk/integrations/ve_code_pipeline/__init__.py +13 -0
  70. veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
  71. veadk/integrations/ve_cozeloop/__init__.py +13 -0
  72. veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
  73. veadk/integrations/ve_cr/__init__.py +13 -0
  74. veadk/integrations/ve_cr/ve_cr.py +220 -0
  75. veadk/integrations/ve_faas/__init__.py +13 -0
  76. veadk/integrations/ve_faas/template/cookiecutter.json +15 -0
  77. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  78. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  79. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +6 -0
  80. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +106 -0
  81. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +13 -0
  82. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +25 -0
  83. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +202 -0
  84. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -0
  85. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +49 -0
  86. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +14 -0
  87. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +27 -0
  88. veadk/integrations/ve_faas/ve_faas.py +754 -0
  89. veadk/integrations/ve_faas/ve_faas_utils.py +408 -0
  90. veadk/integrations/ve_faas/web_template/cookiecutter.json +20 -0
  91. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  92. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  93. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
  94. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +44 -0
  95. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
  96. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
  97. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
  98. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
  99. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
  100. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
  101. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
  102. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
  103. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
  104. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
  105. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
  106. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
  107. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
  108. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
  109. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
  110. veadk/integrations/ve_identity/__init__.py +110 -0
  111. veadk/integrations/ve_identity/auth_config.py +261 -0
  112. veadk/integrations/ve_identity/auth_mixins.py +650 -0
  113. veadk/integrations/ve_identity/auth_processor.py +385 -0
  114. veadk/integrations/ve_identity/function_tool.py +158 -0
  115. veadk/integrations/ve_identity/identity_client.py +864 -0
  116. veadk/integrations/ve_identity/mcp_tool.py +181 -0
  117. veadk/integrations/ve_identity/mcp_toolset.py +431 -0
  118. veadk/integrations/ve_identity/models.py +228 -0
  119. veadk/integrations/ve_identity/token_manager.py +188 -0
  120. veadk/integrations/ve_identity/utils.py +151 -0
  121. veadk/integrations/ve_prompt_pilot/__init__.py +13 -0
  122. veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +85 -0
  123. veadk/integrations/ve_tls/__init__.py +13 -0
  124. veadk/integrations/ve_tls/utils.py +116 -0
  125. veadk/integrations/ve_tls/ve_tls.py +212 -0
  126. veadk/integrations/ve_tos/ve_tos.py +710 -0
  127. veadk/integrations/ve_viking_db_memory/__init__.py +13 -0
  128. veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +308 -0
  129. veadk/knowledgebase/__init__.py +17 -0
  130. veadk/knowledgebase/backends/__init__.py +13 -0
  131. veadk/knowledgebase/backends/base_backend.py +72 -0
  132. veadk/knowledgebase/backends/in_memory_backend.py +91 -0
  133. veadk/knowledgebase/backends/opensearch_backend.py +162 -0
  134. veadk/knowledgebase/backends/redis_backend.py +172 -0
  135. veadk/knowledgebase/backends/utils.py +92 -0
  136. veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +608 -0
  137. veadk/knowledgebase/entry.py +25 -0
  138. veadk/knowledgebase/knowledgebase.py +307 -0
  139. veadk/memory/__init__.py +35 -0
  140. veadk/memory/long_term_memory.py +365 -0
  141. veadk/memory/long_term_memory_backends/__init__.py +13 -0
  142. veadk/memory/long_term_memory_backends/base_backend.py +35 -0
  143. veadk/memory/long_term_memory_backends/in_memory_backend.py +67 -0
  144. veadk/memory/long_term_memory_backends/mem0_backend.py +155 -0
  145. veadk/memory/long_term_memory_backends/opensearch_backend.py +124 -0
  146. veadk/memory/long_term_memory_backends/redis_backend.py +140 -0
  147. veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +189 -0
  148. veadk/memory/short_term_memory.py +252 -0
  149. veadk/memory/short_term_memory_backends/__init__.py +13 -0
  150. veadk/memory/short_term_memory_backends/base_backend.py +31 -0
  151. veadk/memory/short_term_memory_backends/mysql_backend.py +49 -0
  152. veadk/memory/short_term_memory_backends/postgresql_backend.py +49 -0
  153. veadk/memory/short_term_memory_backends/sqlite_backend.py +55 -0
  154. veadk/memory/short_term_memory_processor.py +100 -0
  155. veadk/processors/__init__.py +26 -0
  156. veadk/processors/base_run_processor.py +120 -0
  157. veadk/prompts/__init__.py +13 -0
  158. veadk/prompts/agent_default_prompt.py +30 -0
  159. veadk/prompts/prompt_evaluator.py +20 -0
  160. veadk/prompts/prompt_memory_processor.py +55 -0
  161. veadk/prompts/prompt_optimization.py +150 -0
  162. veadk/runner.py +732 -0
  163. veadk/tools/__init__.py +13 -0
  164. veadk/tools/builtin_tools/__init__.py +13 -0
  165. veadk/tools/builtin_tools/agent_authorization.py +94 -0
  166. veadk/tools/builtin_tools/generate_image.py +23 -0
  167. veadk/tools/builtin_tools/image_edit.py +300 -0
  168. veadk/tools/builtin_tools/image_generate.py +446 -0
  169. veadk/tools/builtin_tools/lark.py +67 -0
  170. veadk/tools/builtin_tools/las.py +24 -0
  171. veadk/tools/builtin_tools/link_reader.py +66 -0
  172. veadk/tools/builtin_tools/llm_shield.py +381 -0
  173. veadk/tools/builtin_tools/load_knowledgebase.py +97 -0
  174. veadk/tools/builtin_tools/mcp_router.py +29 -0
  175. veadk/tools/builtin_tools/run_code.py +113 -0
  176. veadk/tools/builtin_tools/tts.py +253 -0
  177. veadk/tools/builtin_tools/vesearch.py +49 -0
  178. veadk/tools/builtin_tools/video_generate.py +363 -0
  179. veadk/tools/builtin_tools/web_scraper.py +76 -0
  180. veadk/tools/builtin_tools/web_search.py +83 -0
  181. veadk/tools/demo_tools.py +58 -0
  182. veadk/tools/load_knowledgebase_tool.py +149 -0
  183. veadk/tools/sandbox/__init__.py +13 -0
  184. veadk/tools/sandbox/browser_sandbox.py +37 -0
  185. veadk/tools/sandbox/code_sandbox.py +40 -0
  186. veadk/tools/sandbox/computer_sandbox.py +34 -0
  187. veadk/tracing/__init__.py +13 -0
  188. veadk/tracing/base_tracer.py +58 -0
  189. veadk/tracing/telemetry/__init__.py +13 -0
  190. veadk/tracing/telemetry/attributes/attributes.py +29 -0
  191. veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +180 -0
  192. veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +858 -0
  193. veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +152 -0
  194. veadk/tracing/telemetry/attributes/extractors/types.py +164 -0
  195. veadk/tracing/telemetry/exporters/__init__.py +13 -0
  196. veadk/tracing/telemetry/exporters/apmplus_exporter.py +558 -0
  197. veadk/tracing/telemetry/exporters/base_exporter.py +39 -0
  198. veadk/tracing/telemetry/exporters/cozeloop_exporter.py +129 -0
  199. veadk/tracing/telemetry/exporters/inmemory_exporter.py +248 -0
  200. veadk/tracing/telemetry/exporters/tls_exporter.py +139 -0
  201. veadk/tracing/telemetry/opentelemetry_tracer.py +320 -0
  202. veadk/tracing/telemetry/telemetry.py +411 -0
  203. veadk/types.py +47 -0
  204. veadk/utils/__init__.py +13 -0
  205. veadk/utils/audio_manager.py +95 -0
  206. veadk/utils/auth.py +294 -0
  207. veadk/utils/logger.py +59 -0
  208. veadk/utils/mcp_utils.py +44 -0
  209. veadk/utils/misc.py +184 -0
  210. veadk/utils/patches.py +101 -0
  211. veadk/utils/volcengine_sign.py +205 -0
  212. veadk/version.py +15 -0
  213. veadk_python-0.2.27.dist-info/METADATA +373 -0
  214. veadk_python-0.2.27.dist-info/RECORD +218 -0
  215. veadk_python-0.2.27.dist-info/WHEEL +5 -0
  216. veadk_python-0.2.27.dist-info/entry_points.txt +2 -0
  217. veadk_python-0.2.27.dist-info/licenses/LICENSE +201 -0
  218. veadk_python-0.2.27.dist-info/top_level.txt +1 -0
veadk/agent.py ADDED
@@ -0,0 +1,402 @@
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 __future__ import annotations
16
+
17
+ import os
18
+ from typing import Optional, Union
19
+
20
+ # If user didn't set LITELLM_LOCAL_MODEL_COST_MAP, set it to True
21
+ # to enable local model cost map.
22
+ # This value is `false` by default, which brings heavy performance burden,
23
+ # for instance, importing `Litellm` needs about 10s latency.
24
+ if not os.getenv("LITELLM_LOCAL_MODEL_COST_MAP"):
25
+ os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
26
+
27
+ from google.adk.agents import LlmAgent, RunConfig
28
+ from google.adk.agents.base_agent import BaseAgent
29
+ from google.adk.agents.llm_agent import InstructionProvider, ToolUnion
30
+ from google.adk.agents.run_config import StreamingMode
31
+ from google.adk.models.lite_llm import LiteLlm
32
+ from google.adk.runners import Runner
33
+ from google.genai import types
34
+ from pydantic import ConfigDict, Field
35
+ from typing_extensions import Any
36
+
37
+ from veadk.config import settings
38
+ from veadk.consts import (
39
+ DEFAULT_AGENT_NAME,
40
+ DEFAULT_MODEL_EXTRA_CONFIG,
41
+ )
42
+ from veadk.evaluation import EvalSetRecorder
43
+ from veadk.knowledgebase import KnowledgeBase
44
+ from veadk.memory.long_term_memory import LongTermMemory
45
+ from veadk.memory.short_term_memory import ShortTermMemory
46
+ from veadk.processors import BaseRunProcessor, NoOpRunProcessor
47
+ from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
48
+ from veadk.tracing.base_tracer import BaseTracer
49
+ from veadk.utils.logger import get_logger
50
+ from veadk.utils.patches import patch_asyncio, patch_tracer
51
+ from veadk.version import VERSION
52
+
53
+ patch_tracer()
54
+ patch_asyncio()
55
+ logger = get_logger(__name__)
56
+
57
+
58
+ class Agent(LlmAgent):
59
+ """LLM-based Agent with Volcengine capabilities.
60
+
61
+ This class represents an intelligent agent powered by LLMs (Large Language Models),
62
+ integrated with Volcengine's AI framework. It supports memory modules, sub-agents,
63
+ tracers, knowledge bases, and other advanced features for A2A (Agent-to-Agent)
64
+ or user-facing scenarios.
65
+
66
+ Attributes:
67
+ name (str): The name of the agent.
68
+ description (str): A description of the agent, useful in A2A scenarios.
69
+ instruction (Union[str, InstructionProvider]): The instruction or instruction provider.
70
+ model_name (str): Name of the model used by the agent.
71
+ model_provider (str): Provider of the model (e.g., openai).
72
+ model_api_base (str): The base URL of the model API.
73
+ model_api_key (str): The API key for accessing the model.
74
+ model_extra_config (dict): Extra configurations to include in model requests.
75
+ tools (list[ToolUnion]): Tools available to the agent.
76
+ sub_agents (list[BaseAgent]): Sub-agents managed by this agent.
77
+ knowledgebase (Optional[KnowledgeBase]): Knowledge base attached to the agent.
78
+ short_term_memory (Optional[ShortTermMemory]): Session-based memory for temporary context.
79
+ long_term_memory (Optional[LongTermMemory]): Cross-session memory for persistent user context.
80
+ tracers (list[BaseTracer]): List of tracers used for telemetry and monitoring.
81
+ """
82
+
83
+ model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
84
+
85
+ name: str = DEFAULT_AGENT_NAME
86
+ description: str = DEFAULT_DESCRIPTION
87
+ instruction: Union[str, InstructionProvider] = DEFAULT_INSTRUCTION
88
+
89
+ model_name: str = Field(default_factory=lambda: settings.model.name)
90
+ model_provider: str = Field(default_factory=lambda: settings.model.provider)
91
+ model_api_base: str = Field(default_factory=lambda: settings.model.api_base)
92
+ model_api_key: str = Field(default_factory=lambda: settings.model.api_key)
93
+ model_extra_config: dict = Field(default_factory=dict)
94
+
95
+ tools: list[ToolUnion] = []
96
+
97
+ sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
98
+
99
+ knowledgebase: Optional[KnowledgeBase] = None
100
+
101
+ short_term_memory: Optional[ShortTermMemory] = None
102
+ long_term_memory: Optional[LongTermMemory] = None
103
+
104
+ tracers: list[BaseTracer] = []
105
+
106
+ run_processor: Optional[BaseRunProcessor] = Field(default=None, exclude=True)
107
+ """Optional run processor for intercepting and processing agent execution flows.
108
+
109
+ The run processor can be used to implement cross-cutting concerns such as:
110
+ - Authentication flows (e.g., OAuth2 via VeIdentity)
111
+ - Request/response logging
112
+ - Error handling and retry logic
113
+ - Performance monitoring
114
+
115
+ If not provided, a NoOpRunProcessor will be used by default.
116
+
117
+ Example:
118
+ from veadk.integrations.ve_identity import AuthRequestProcessor
119
+
120
+ agent = Agent(
121
+ name="my-agent",
122
+ run_processor=AuthRequestProcessor()
123
+ )
124
+ """
125
+
126
+ enable_authz: bool = False
127
+
128
+ def model_post_init(self, __context: Any) -> None:
129
+ super().model_post_init(None) # for sub_agents init
130
+
131
+ # Initialize run_processor if not provided
132
+ if self.run_processor is None:
133
+ self.run_processor = NoOpRunProcessor()
134
+
135
+ # combine user model config with VeADK defaults
136
+ headers = DEFAULT_MODEL_EXTRA_CONFIG["extra_headers"].copy()
137
+ body = DEFAULT_MODEL_EXTRA_CONFIG["extra_body"].copy()
138
+
139
+ if self.model_extra_config:
140
+ user_headers = self.model_extra_config.get("extra_headers", {})
141
+ user_body = self.model_extra_config.get("extra_body", {})
142
+
143
+ headers |= user_headers
144
+ body |= user_body
145
+
146
+ self.model_extra_config |= {
147
+ "extra_headers": headers,
148
+ "extra_body": body,
149
+ }
150
+
151
+ logger.info(f"Model extra config: {self.model_extra_config}")
152
+
153
+ if not self.model:
154
+ self.model = LiteLlm(
155
+ model=f"{self.model_provider}/{self.model_name}",
156
+ api_key=self.model_api_key,
157
+ api_base=self.model_api_base,
158
+ **self.model_extra_config,
159
+ )
160
+ logger.debug(
161
+ f"LiteLLM client created with config: {self.model_extra_config}"
162
+ )
163
+ else:
164
+ logger.warning(
165
+ "You are trying to use your own LiteLLM client, some default request headers may be missing."
166
+ )
167
+
168
+ self._prepare_tracers()
169
+
170
+ if self.knowledgebase:
171
+ from veadk.tools.builtin_tools.load_knowledgebase import (
172
+ LoadKnowledgebaseTool,
173
+ )
174
+
175
+ load_knowledgebase_tool = LoadKnowledgebaseTool(
176
+ knowledgebase=self.knowledgebase
177
+ )
178
+ self.tools.append(load_knowledgebase_tool)
179
+
180
+ if self.long_term_memory is not None:
181
+ from google.adk.tools import load_memory
182
+
183
+ if hasattr(load_memory, "custom_metadata"):
184
+ if not load_memory.custom_metadata:
185
+ load_memory.custom_metadata = {}
186
+ load_memory.custom_metadata["backend"] = self.long_term_memory.backend
187
+ self.tools.append(load_memory)
188
+
189
+ if self.enable_authz:
190
+ from veadk.tools.builtin_tools.agent_authorization import (
191
+ check_agent_authorization,
192
+ )
193
+
194
+ if self.before_agent_callback:
195
+ if isinstance(self.before_agent_callback, list):
196
+ self.before_agent_callback.append(check_agent_authorization)
197
+ else:
198
+ self.before_agent_callback = [
199
+ self.before_agent_callback,
200
+ check_agent_authorization,
201
+ ]
202
+ else:
203
+ self.before_agent_callback = check_agent_authorization
204
+
205
+ logger.info(f"VeADK version: {VERSION}")
206
+
207
+ logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
208
+ logger.debug(
209
+ f"Agent: {self.model_dump(include={'name', 'model_name', 'model_api_base', 'tools'})}"
210
+ )
211
+
212
+ async def _run(
213
+ self,
214
+ runner,
215
+ user_id: str,
216
+ session_id: str,
217
+ message: types.Content,
218
+ stream: bool,
219
+ run_processor: Optional[BaseRunProcessor] = None,
220
+ ):
221
+ """Internal run method with run processor support.
222
+
223
+ Args:
224
+ runner: The Runner instance.
225
+ user_id: User ID for the session.
226
+ session_id: Session ID.
227
+ message: The message to send.
228
+ stream: Whether to stream the output.
229
+ run_processor: Optional run processor to use. If not provided, uses self.run_processor.
230
+
231
+ Returns:
232
+ The final output string.
233
+ """
234
+ stream_mode = StreamingMode.SSE if stream else StreamingMode.NONE
235
+
236
+ # Use provided run_processor or fall back to instance's run_processor
237
+ processor = run_processor or self.run_processor
238
+
239
+ @processor.process_run(runner=runner, message=message)
240
+ async def event_generator():
241
+ async for event in runner.run_async(
242
+ user_id=user_id,
243
+ session_id=session_id,
244
+ new_message=message,
245
+ run_config=RunConfig(streaming_mode=stream_mode),
246
+ ):
247
+ if event.get_function_calls():
248
+ for function_call in event.get_function_calls():
249
+ logger.debug(f"Function call: {function_call}")
250
+ elif (
251
+ event.content is not None
252
+ and event.content.parts[0].text is not None
253
+ and len(event.content.parts[0].text.strip()) > 0
254
+ ):
255
+ yield event.content.parts[0].text
256
+
257
+ final_output = ""
258
+ async for chunk in event_generator():
259
+ if stream:
260
+ print(chunk, end="", flush=True)
261
+ final_output += chunk
262
+ if stream:
263
+ print() # end with a new line
264
+
265
+ return final_output
266
+
267
+ def _prepare_tracers(self):
268
+ enable_apmplus_tracer = os.getenv("ENABLE_APMPLUS", "false").lower() == "true"
269
+ enable_cozeloop_tracer = os.getenv("ENABLE_COZELOOP", "false").lower() == "true"
270
+ enable_tls_tracer = os.getenv("ENABLE_TLS", "false").lower() == "true"
271
+
272
+ if not (enable_apmplus_tracer or enable_cozeloop_tracer or enable_tls_tracer):
273
+ logger.info("No exporter enabled by env, skip prepare tracers.")
274
+ return
275
+
276
+ if not self.tracers:
277
+ from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer
278
+
279
+ self.tracers.append(OpentelemetryTracer())
280
+
281
+ exporters = self.tracers[0].exporters # type: ignore
282
+
283
+ from veadk.tracing.telemetry.exporters.apmplus_exporter import APMPlusExporter
284
+ from veadk.tracing.telemetry.exporters.cozeloop_exporter import CozeloopExporter
285
+ from veadk.tracing.telemetry.exporters.tls_exporter import TLSExporter
286
+
287
+ if enable_apmplus_tracer and not any(
288
+ isinstance(e, APMPlusExporter) for e in exporters
289
+ ):
290
+ self.tracers[0].exporters.append(APMPlusExporter()) # type: ignore
291
+ logger.info("Enable APMPlus exporter by env.")
292
+
293
+ if enable_cozeloop_tracer and not any(
294
+ isinstance(e, CozeloopExporter) for e in exporters
295
+ ):
296
+ self.tracers[0].exporters.append(CozeloopExporter()) # type: ignore
297
+ logger.info("Enable CozeLoop exporter by env.")
298
+
299
+ if enable_tls_tracer and not any(isinstance(e, TLSExporter) for e in exporters):
300
+ self.tracers[0].exporters.append(TLSExporter()) # type: ignore
301
+ logger.info("Enable TLS exporter by env.")
302
+
303
+ logger.debug(
304
+ f"Opentelemetry Tracer init {len(self.tracers[0].exporters)} exporters" # type: ignore
305
+ )
306
+
307
+ async def run(
308
+ self,
309
+ prompt: str | list[str],
310
+ stream: bool = False,
311
+ app_name: str = "veadk_app",
312
+ user_id: str = "veadk_user",
313
+ session_id="veadk_session",
314
+ load_history_sessions_from_db: bool = False,
315
+ db_url: str = "",
316
+ collect_runtime_data: bool = False,
317
+ eval_set_id: str = "",
318
+ save_session_to_memory: bool = False,
319
+ run_processor: Optional[BaseRunProcessor] = None,
320
+ ):
321
+ """Running the agent. The runner and session service will be created automatically.
322
+
323
+ For production, consider using Google-ADK runner to run agent, rather than invoking this method.
324
+
325
+ Args:
326
+ prompt (str | list[str]): The prompt to run the agent.
327
+ stream (bool, optional): Whether to stream the output. Defaults to False.
328
+ app_name (str, optional): The name of the application. Defaults to "veadk_app".
329
+ user_id (str, optional): The id of the user. Defaults to "veadk_user".
330
+ session_id (str, optional): The id of the session. Defaults to "veadk_session".
331
+ load_history_sessions_from_db (bool, optional): Whether to load history sessions from database. Defaults to False.
332
+ db_url (str, optional): The url of the database. Defaults to "".
333
+ collect_runtime_data (bool, optional): Whether to collect runtime data. Defaults to False.
334
+ eval_set_id (str, optional): The id of the eval set. Defaults to "".
335
+ save_session_to_memory (bool, optional): Whether to save this turn session to memory. Defaults to False.
336
+ run_processor (Optional[BaseRunProcessor], optional): Optional run processor to use for this run.
337
+ If not provided, uses the agent's default run_processor. Defaults to None.
338
+ """
339
+
340
+ logger.warning(
341
+ "Running agent in this function is only for development and testing, do not use this function in production. For production, consider using `Google ADK Runner` to run agent, rather than invoking this method."
342
+ )
343
+ logger.info(
344
+ f"Run agent {self.name}: app_name: {app_name}, user_id: {user_id}, session_id: {session_id}."
345
+ )
346
+ prompt = [prompt] if isinstance(prompt, str) else prompt
347
+
348
+ # memory service
349
+ short_term_memory = ShortTermMemory(
350
+ backend="database" if load_history_sessions_from_db else "local",
351
+ db_url=db_url,
352
+ )
353
+ session_service = short_term_memory.session_service
354
+ await short_term_memory.create_session(
355
+ app_name=app_name, user_id=user_id, session_id=session_id
356
+ )
357
+
358
+ # runner
359
+ runner = Runner(
360
+ agent=self,
361
+ app_name=app_name,
362
+ session_service=session_service,
363
+ memory_service=self.long_term_memory,
364
+ )
365
+
366
+ logger.info(f"Begin to process prompt {prompt}")
367
+ # run
368
+ final_output = ""
369
+ for _prompt in prompt:
370
+ message = types.Content(role="user", parts=[types.Part(text=_prompt)])
371
+ final_output = await self._run(
372
+ runner, user_id, session_id, message, stream, run_processor
373
+ )
374
+
375
+ # VeADK features
376
+ if save_session_to_memory:
377
+ assert self.long_term_memory is not None, (
378
+ "Long-term memory is not initialized in agent"
379
+ )
380
+ session = await session_service.get_session(
381
+ app_name=app_name,
382
+ user_id=user_id,
383
+ session_id=session_id,
384
+ )
385
+ if session:
386
+ await self.long_term_memory.add_session_to_memory(session)
387
+ logger.info(f"Add session `{session.id}` to your long-term memory.")
388
+ else:
389
+ logger.error(
390
+ f"Session {session_id} not found in session service, cannot save to long-term memory."
391
+ )
392
+
393
+ if collect_runtime_data:
394
+ eval_set_recorder = EvalSetRecorder(session_service, eval_set_id)
395
+ dump_path = await eval_set_recorder.dump(app_name, user_id, session_id)
396
+ self._dump_path = dump_path # just for test/debug/instrumentation
397
+
398
+ if self.tracers:
399
+ for tracer in self.tracers:
400
+ tracer.dump(user_id=user_id, session_id=session_id)
401
+
402
+ return final_output
veadk/agent_builder.py ADDED
@@ -0,0 +1,93 @@
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 importlib
16
+
17
+ from google.adk.agents import BaseAgent
18
+ from omegaconf import OmegaConf
19
+
20
+ from veadk.a2a.remote_ve_agent import RemoteVeAgent
21
+ from veadk.agent import Agent
22
+ from veadk.agents.loop_agent import LoopAgent
23
+ from veadk.agents.parallel_agent import ParallelAgent
24
+ from veadk.agents.sequential_agent import SequentialAgent
25
+ from veadk.utils.logger import get_logger
26
+
27
+ logger = get_logger(__name__)
28
+
29
+ AGENT_TYPES = {
30
+ "Agent": Agent,
31
+ "SequentialAgent": SequentialAgent,
32
+ "ParallelAgent": ParallelAgent,
33
+ "LoopAgent": LoopAgent,
34
+ "RemoteVeAgent": RemoteVeAgent,
35
+ }
36
+
37
+
38
+ class AgentBuilder:
39
+ def __init__(self) -> None:
40
+ pass
41
+
42
+ def _build(self, agent_config: dict) -> BaseAgent:
43
+ logger.info(f"Building agent with config: {agent_config}")
44
+
45
+ sub_agents = []
46
+ if agent_config.get("sub_agents", None):
47
+ for sub_agent_config in agent_config["sub_agents"]:
48
+ agent = self._build(sub_agent_config)
49
+ sub_agents.append(agent)
50
+ agent_config.pop("sub_agents")
51
+
52
+ tools = []
53
+ if agent_config.get("tools", []):
54
+ for tool in agent_config["tools"]:
55
+ name = tool["name"]
56
+ module_name, func_name = name.rsplit(".", 1)
57
+ module = importlib.import_module(module_name)
58
+ func = getattr(module, func_name)
59
+
60
+ tools.append(func)
61
+ agent_config.pop("tools")
62
+
63
+ agent_cls = AGENT_TYPES[agent_config["type"]]
64
+ agent = agent_cls(**agent_config, sub_agents=sub_agents, tools=tools)
65
+
66
+ logger.debug("Build agent done.")
67
+
68
+ return agent
69
+
70
+ def _read_config(self, path: str) -> dict:
71
+ """Read config file (from `path`) to a in-memory dict."""
72
+ assert path.endswith(".yaml"), "Agent config file must be a `.yaml` file."
73
+
74
+ config = OmegaConf.load(path)
75
+ config_dict = OmegaConf.to_container(config, resolve=True)
76
+
77
+ assert isinstance(config_dict, dict), (
78
+ "Parsed config must in `dict` format. Pls check your building file format."
79
+ )
80
+
81
+ return config_dict
82
+
83
+ def build(
84
+ self,
85
+ path: str,
86
+ root_agent_identifier: str = "root_agent",
87
+ ) -> BaseAgent:
88
+ config = self._read_config(path)
89
+
90
+ agent_config = config[root_agent_identifier]
91
+ agent = self._build(agent_config)
92
+
93
+ return agent
@@ -0,0 +1,68 @@
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 __future__ import annotations
16
+
17
+ from google.adk.agents import LoopAgent as GoogleADKLoopAgent
18
+ from google.adk.agents.base_agent import BaseAgent
19
+ from pydantic import ConfigDict, Field
20
+ from typing_extensions import Any
21
+
22
+ from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
23
+ from veadk.tracing.base_tracer import BaseTracer
24
+ from veadk.utils.logger import get_logger
25
+ from veadk.utils.patches import patch_asyncio
26
+
27
+ patch_asyncio()
28
+ logger = get_logger(__name__)
29
+
30
+
31
+ class LoopAgent(GoogleADKLoopAgent):
32
+ """Loop Agent with several sub agents.
33
+
34
+ This agent is capable of looping through and executing all sub-agents sequentially
35
+ or based on specific conditions. It is designed to operate in environments where
36
+ multiple agents need to work together in a looped execution flow, such as handling
37
+ complex, multi-step tasks or workflows. The agent integrates Volcengine’s AI
38
+ capabilities and supports a variety of tools and tracers for enhanced functionality
39
+ and performance monitoring.
40
+
41
+ Attributes:
42
+ model_config (ConfigDict): Configuration dictionary for the model.
43
+ name (str): The name of the agent, default is "veLoopAgent".
44
+ description (str): A description of the agent, helpful in A2A scenarios.
45
+ instruction (str): Instructions or principles for function calling and agent execution.
46
+ sub_agents (list[BaseAgent]): A list of sub-agents managed by the loop agent. Each sub-agent
47
+ is executed in a looped sequence based on the agent's logic.
48
+ tracers (list[BaseTracer]): A list of tracers used for monitoring the agent's performance
49
+ and behavior during execution.
50
+
51
+ Examples:
52
+
53
+ """
54
+
55
+ model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
56
+
57
+ name: str = "veLoopAgent"
58
+ description: str = DEFAULT_DESCRIPTION
59
+ instruction: str = DEFAULT_INSTRUCTION
60
+
61
+ sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
62
+
63
+ tracers: list[BaseTracer] = []
64
+
65
+ def model_post_init(self, __context: Any) -> None:
66
+ super().model_post_init(None) # for sub_agents init
67
+
68
+ logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
@@ -0,0 +1,72 @@
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 __future__ import annotations
16
+
17
+ from google.adk.agents import ParallelAgent as GoogleADKParallelAgent
18
+ from google.adk.agents.base_agent import BaseAgent
19
+ from pydantic import ConfigDict, Field
20
+ from typing_extensions import Any
21
+
22
+ from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
23
+ from veadk.tracing.base_tracer import BaseTracer
24
+ from veadk.utils.logger import get_logger
25
+ from veadk.utils.patches import patch_asyncio
26
+
27
+ patch_asyncio()
28
+ logger = get_logger(__name__)
29
+
30
+
31
+ class ParallelAgent(GoogleADKParallelAgent):
32
+ """LLM-based Agent that can execute sub-agents in parallel.
33
+
34
+ This agent is capable of executing multiple sub-agents concurrently, making it suitable
35
+ for scenarios that require parallel execution of multiple tasks or operations. By leveraging
36
+ parallelism, the agent can handle more complex workflows and improve efficiency by performing
37
+ independent tasks simultaneously. This design is ideal for scenarios where tasks are independent
38
+ and can benefit from reduced execution time.
39
+
40
+ Attributes:
41
+ model_config (ConfigDict): Configuration dictionary for the model.
42
+ name (str): The name of the agent, default is "veParallelAgent".
43
+ description (str): A description of the agent, useful in A2A scenarios.
44
+ instruction (str): Instructions or principles for function calling and agent execution.
45
+ sub_agents (list[BaseAgent]): A list of sub-agents managed by the parallel agent.
46
+ Each sub-agent is executed concurrently.
47
+ tracers (list[BaseTracer]): A list of tracers used for monitoring the agent's performance
48
+ and behavior during parallel execution.
49
+
50
+ Examples:
51
+
52
+ """
53
+
54
+ model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
55
+
56
+ name: str = "veParallelAgent"
57
+ description: str = DEFAULT_DESCRIPTION
58
+ instruction: str = DEFAULT_INSTRUCTION
59
+
60
+ sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
61
+
62
+ tracers: list[BaseTracer] = []
63
+
64
+ def model_post_init(self, __context: Any) -> None:
65
+ super().model_post_init(None) # for sub_agents init
66
+
67
+ if self.tracers:
68
+ logger.warning(
69
+ "Enable tracing in ParallelAgent may cause OpenTelemetry context error. Issue see https://github.com/google/adk-python/issues/1670"
70
+ )
71
+
72
+ logger.info(f"{self.__class__.__name__} `{self.name}` init done.")