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.
- veadk/__init__.py +37 -0
- veadk/a2a/__init__.py +13 -0
- veadk/a2a/agent_card.py +45 -0
- veadk/a2a/remote_ve_agent.py +390 -0
- veadk/a2a/utils/__init__.py +13 -0
- veadk/a2a/utils/agent_to_a2a.py +170 -0
- veadk/a2a/ve_a2a_server.py +93 -0
- veadk/a2a/ve_agent_executor.py +78 -0
- veadk/a2a/ve_middlewares.py +313 -0
- veadk/a2a/ve_task_store.py +37 -0
- veadk/agent.py +402 -0
- veadk/agent_builder.py +93 -0
- veadk/agents/loop_agent.py +68 -0
- veadk/agents/parallel_agent.py +72 -0
- veadk/agents/sequential_agent.py +64 -0
- veadk/auth/__init__.py +13 -0
- veadk/auth/base_auth.py +22 -0
- veadk/auth/ve_credential_service.py +203 -0
- veadk/auth/veauth/__init__.py +13 -0
- veadk/auth/veauth/apmplus_veauth.py +58 -0
- veadk/auth/veauth/ark_veauth.py +75 -0
- veadk/auth/veauth/base_veauth.py +50 -0
- veadk/auth/veauth/cozeloop_veauth.py +13 -0
- veadk/auth/veauth/opensearch_veauth.py +75 -0
- veadk/auth/veauth/postgresql_veauth.py +75 -0
- veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
- veadk/auth/veauth/speech_veauth.py +54 -0
- veadk/auth/veauth/utils.py +69 -0
- veadk/auth/veauth/vesearch_veauth.py +62 -0
- veadk/auth/veauth/viking_mem0_veauth.py +91 -0
- veadk/cli/__init__.py +13 -0
- veadk/cli/cli.py +58 -0
- veadk/cli/cli_clean.py +87 -0
- veadk/cli/cli_create.py +163 -0
- veadk/cli/cli_deploy.py +233 -0
- veadk/cli/cli_eval.py +215 -0
- veadk/cli/cli_init.py +214 -0
- veadk/cli/cli_kb.py +110 -0
- veadk/cli/cli_pipeline.py +285 -0
- veadk/cli/cli_prompt.py +86 -0
- veadk/cli/cli_update.py +106 -0
- veadk/cli/cli_uploadevalset.py +139 -0
- veadk/cli/cli_web.py +143 -0
- veadk/cloud/__init__.py +13 -0
- veadk/cloud/cloud_agent_engine.py +485 -0
- veadk/cloud/cloud_app.py +475 -0
- veadk/config.py +115 -0
- veadk/configs/__init__.py +13 -0
- veadk/configs/auth_configs.py +133 -0
- veadk/configs/database_configs.py +132 -0
- veadk/configs/model_configs.py +78 -0
- veadk/configs/tool_configs.py +54 -0
- veadk/configs/tracing_configs.py +110 -0
- veadk/consts.py +74 -0
- veadk/evaluation/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/adk_evaluator.py +302 -0
- veadk/evaluation/base_evaluator.py +642 -0
- veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +339 -0
- veadk/evaluation/eval_set_file_loader.py +48 -0
- veadk/evaluation/eval_set_recorder.py +146 -0
- veadk/evaluation/types.py +65 -0
- veadk/evaluation/utils/prometheus.py +196 -0
- veadk/integrations/__init__.py +13 -0
- veadk/integrations/ve_apig/__init__.py +13 -0
- veadk/integrations/ve_apig/ve_apig.py +349 -0
- veadk/integrations/ve_apig/ve_apig_utils.py +332 -0
- veadk/integrations/ve_code_pipeline/__init__.py +13 -0
- veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
- veadk/integrations/ve_cozeloop/__init__.py +13 -0
- veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
- veadk/integrations/ve_cr/__init__.py +13 -0
- veadk/integrations/ve_cr/ve_cr.py +220 -0
- veadk/integrations/ve_faas/__init__.py +13 -0
- veadk/integrations/ve_faas/template/cookiecutter.json +15 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +6 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +106 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +13 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +25 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +202 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +49 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +14 -0
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +27 -0
- veadk/integrations/ve_faas/ve_faas.py +754 -0
- veadk/integrations/ve_faas/ve_faas_utils.py +408 -0
- veadk/integrations/ve_faas/web_template/cookiecutter.json +20 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +44 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
- veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
- veadk/integrations/ve_identity/__init__.py +110 -0
- veadk/integrations/ve_identity/auth_config.py +261 -0
- veadk/integrations/ve_identity/auth_mixins.py +650 -0
- veadk/integrations/ve_identity/auth_processor.py +385 -0
- veadk/integrations/ve_identity/function_tool.py +158 -0
- veadk/integrations/ve_identity/identity_client.py +864 -0
- veadk/integrations/ve_identity/mcp_tool.py +181 -0
- veadk/integrations/ve_identity/mcp_toolset.py +431 -0
- veadk/integrations/ve_identity/models.py +228 -0
- veadk/integrations/ve_identity/token_manager.py +188 -0
- veadk/integrations/ve_identity/utils.py +151 -0
- veadk/integrations/ve_prompt_pilot/__init__.py +13 -0
- veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +85 -0
- veadk/integrations/ve_tls/__init__.py +13 -0
- veadk/integrations/ve_tls/utils.py +116 -0
- veadk/integrations/ve_tls/ve_tls.py +212 -0
- veadk/integrations/ve_tos/ve_tos.py +710 -0
- veadk/integrations/ve_viking_db_memory/__init__.py +13 -0
- veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +308 -0
- veadk/knowledgebase/__init__.py +17 -0
- veadk/knowledgebase/backends/__init__.py +13 -0
- veadk/knowledgebase/backends/base_backend.py +72 -0
- veadk/knowledgebase/backends/in_memory_backend.py +91 -0
- veadk/knowledgebase/backends/opensearch_backend.py +162 -0
- veadk/knowledgebase/backends/redis_backend.py +172 -0
- veadk/knowledgebase/backends/utils.py +92 -0
- veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +608 -0
- veadk/knowledgebase/entry.py +25 -0
- veadk/knowledgebase/knowledgebase.py +307 -0
- veadk/memory/__init__.py +35 -0
- veadk/memory/long_term_memory.py +365 -0
- veadk/memory/long_term_memory_backends/__init__.py +13 -0
- veadk/memory/long_term_memory_backends/base_backend.py +35 -0
- veadk/memory/long_term_memory_backends/in_memory_backend.py +67 -0
- veadk/memory/long_term_memory_backends/mem0_backend.py +155 -0
- veadk/memory/long_term_memory_backends/opensearch_backend.py +124 -0
- veadk/memory/long_term_memory_backends/redis_backend.py +140 -0
- veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +189 -0
- veadk/memory/short_term_memory.py +252 -0
- veadk/memory/short_term_memory_backends/__init__.py +13 -0
- veadk/memory/short_term_memory_backends/base_backend.py +31 -0
- veadk/memory/short_term_memory_backends/mysql_backend.py +49 -0
- veadk/memory/short_term_memory_backends/postgresql_backend.py +49 -0
- veadk/memory/short_term_memory_backends/sqlite_backend.py +55 -0
- veadk/memory/short_term_memory_processor.py +100 -0
- veadk/processors/__init__.py +26 -0
- veadk/processors/base_run_processor.py +120 -0
- veadk/prompts/__init__.py +13 -0
- veadk/prompts/agent_default_prompt.py +30 -0
- veadk/prompts/prompt_evaluator.py +20 -0
- veadk/prompts/prompt_memory_processor.py +55 -0
- veadk/prompts/prompt_optimization.py +150 -0
- veadk/runner.py +732 -0
- veadk/tools/__init__.py +13 -0
- veadk/tools/builtin_tools/__init__.py +13 -0
- veadk/tools/builtin_tools/agent_authorization.py +94 -0
- veadk/tools/builtin_tools/generate_image.py +23 -0
- veadk/tools/builtin_tools/image_edit.py +300 -0
- veadk/tools/builtin_tools/image_generate.py +446 -0
- veadk/tools/builtin_tools/lark.py +67 -0
- veadk/tools/builtin_tools/las.py +24 -0
- veadk/tools/builtin_tools/link_reader.py +66 -0
- veadk/tools/builtin_tools/llm_shield.py +381 -0
- veadk/tools/builtin_tools/load_knowledgebase.py +97 -0
- veadk/tools/builtin_tools/mcp_router.py +29 -0
- veadk/tools/builtin_tools/run_code.py +113 -0
- veadk/tools/builtin_tools/tts.py +253 -0
- veadk/tools/builtin_tools/vesearch.py +49 -0
- veadk/tools/builtin_tools/video_generate.py +363 -0
- veadk/tools/builtin_tools/web_scraper.py +76 -0
- veadk/tools/builtin_tools/web_search.py +83 -0
- veadk/tools/demo_tools.py +58 -0
- veadk/tools/load_knowledgebase_tool.py +149 -0
- veadk/tools/sandbox/__init__.py +13 -0
- veadk/tools/sandbox/browser_sandbox.py +37 -0
- veadk/tools/sandbox/code_sandbox.py +40 -0
- veadk/tools/sandbox/computer_sandbox.py +34 -0
- veadk/tracing/__init__.py +13 -0
- veadk/tracing/base_tracer.py +58 -0
- veadk/tracing/telemetry/__init__.py +13 -0
- veadk/tracing/telemetry/attributes/attributes.py +29 -0
- veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +180 -0
- veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +858 -0
- veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +152 -0
- veadk/tracing/telemetry/attributes/extractors/types.py +164 -0
- veadk/tracing/telemetry/exporters/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +558 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +39 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +129 -0
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +248 -0
- veadk/tracing/telemetry/exporters/tls_exporter.py +139 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +320 -0
- veadk/tracing/telemetry/telemetry.py +411 -0
- veadk/types.py +47 -0
- veadk/utils/__init__.py +13 -0
- veadk/utils/audio_manager.py +95 -0
- veadk/utils/auth.py +294 -0
- veadk/utils/logger.py +59 -0
- veadk/utils/mcp_utils.py +44 -0
- veadk/utils/misc.py +184 -0
- veadk/utils/patches.py +101 -0
- veadk/utils/volcengine_sign.py +205 -0
- veadk/version.py +15 -0
- veadk_python-0.2.27.dist-info/METADATA +373 -0
- veadk_python-0.2.27.dist-info/RECORD +218 -0
- veadk_python-0.2.27.dist-info/WHEEL +5 -0
- veadk_python-0.2.27.dist-info/entry_points.txt +2 -0
- veadk_python-0.2.27.dist-info/licenses/LICENSE +201 -0
- 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.")
|