Skip to content

Commit 374dc3d

Browse files
committed
feat: support workflow agents
1 parent 30a8061 commit 374dc3d

File tree

6 files changed

+212
-6
lines changed

6 files changed

+212
-6
lines changed

veadk/agent.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ class Agent(LlmAgent):
6060
instruction: str = DEFAULT_INSTRUCTION
6161
"""The instruction for the agent, such as principles of function calling."""
6262

63-
# factory
6463
model_name: str = getenv("MODEL_AGENT_NAME", DEFAULT_MODEL_AGENT_NAME)
6564
"""The name of the model for agent running."""
6665

@@ -122,7 +121,7 @@ def model_post_init(self, __context: Any) -> None:
122121
self.after_model_callback.append(tracer.tracer_hook_after_model)
123122
self.after_tool_callback.append(tracer.tracer_hook_after_tool)
124123

125-
logger.info(f"Agent `{self.name}` init done.")
124+
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
126125
logger.debug(
127126
f"Agent: {self.model_dump(include={'name', 'model_name', 'model_api_base', 'tools', 'serve_url'})}"
128127
)

veadk/agents/loop_agent.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
"""LLM-based Agent with Volcengine capabilities."""
33+
34+
model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
35+
"""The model config"""
36+
37+
name: str = "veLoopAgent"
38+
"""The name of the agent."""
39+
40+
description: str = DEFAULT_DESCRIPTION
41+
"""The description of the agent. This will be helpful in A2A scenario."""
42+
43+
instruction: str = DEFAULT_INSTRUCTION
44+
"""The instruction for the agent, such as principles of function calling."""
45+
46+
sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
47+
"""The sub agents provided to agent."""
48+
49+
tracers: list[BaseTracer] = []
50+
"""The tracers provided to agent."""
51+
52+
def model_post_init(self, __context: Any) -> None:
53+
super().model_post_init(None) # for sub_agents init
54+
55+
if self.tracers:
56+
for tracer in self.tracers:
57+
for sub_agent in self.sub_agents:
58+
try:
59+
tracer.do_hooks(sub_agent)
60+
except Exception as e:
61+
logger.warning(
62+
f"Failed to add hooks for sub_agent `{sub_agent.name}`: {e}"
63+
)
64+
65+
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/agents/parallel_agent.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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 with Volcengine capabilities."""
33+
34+
model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
35+
"""The model config"""
36+
37+
name: str = "veParallelAgent"
38+
"""The name of the agent."""
39+
40+
description: str = DEFAULT_DESCRIPTION
41+
"""The description of the agent. This will be helpful in A2A scenario."""
42+
43+
instruction: str = DEFAULT_INSTRUCTION
44+
"""The instruction for the agent, such as principles of function calling."""
45+
46+
sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
47+
"""The sub agents provided to agent."""
48+
49+
tracers: list[BaseTracer] = []
50+
"""The tracers provided to agent."""
51+
52+
def model_post_init(self, __context: Any) -> None:
53+
super().model_post_init(None) # for sub_agents init
54+
55+
if self.tracers:
56+
for tracer in self.tracers:
57+
for sub_agent in self.sub_agents:
58+
try:
59+
tracer.do_hooks(sub_agent)
60+
except Exception as e:
61+
logger.warning(
62+
f"Failed to add hooks for sub_agent `{sub_agent.name}`: {e}"
63+
)
64+
65+
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/agents/sequential_agent.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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 SequentialAgent as GoogleADKSequentialAgent
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 SequentialAgent(GoogleADKSequentialAgent):
32+
"""LLM-based Agent with Volcengine capabilities."""
33+
34+
model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
35+
"""The model config"""
36+
37+
name: str = "veSequentialAgent"
38+
"""The name of the agent."""
39+
40+
description: str = DEFAULT_DESCRIPTION
41+
"""The description of the agent. This will be helpful in A2A scenario."""
42+
43+
instruction: str = DEFAULT_INSTRUCTION
44+
"""The instruction for the agent, such as principles of function calling."""
45+
46+
sub_agents: list[BaseAgent] = Field(default_factory=list, exclude=True)
47+
"""The sub agents provided to agent."""
48+
49+
tracers: list[BaseTracer] = []
50+
"""The tracers provided to agent."""
51+
52+
def model_post_init(self, __context: Any) -> None:
53+
super().model_post_init(None) # for sub_agents init
54+
55+
if self.tracers:
56+
for tracer in self.tracers:
57+
for sub_agent in self.sub_agents:
58+
try:
59+
tracer.do_hooks(sub_agent)
60+
except Exception as e:
61+
logger.warning(
62+
f"Failed to add hooks for sub_agent `{sub_agent.name}`: {e}"
63+
)
64+
65+
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/runner.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
from veadk.a2a.remote_ve_agent import RemoteVeAgent
2323
from veadk.agent import Agent
24+
from veadk.agents.loop_agent import LoopAgent
25+
from veadk.agents.parallel_agent import ParallelAgent
26+
from veadk.agents.sequential_agent import SequentialAgent
2427
from veadk.evaluation import EvalSetRecorder
2528
from veadk.memory.short_term_memory import ShortTermMemory
2629
from veadk.types import MediaMessage
@@ -38,11 +41,13 @@
3841
list[MediaMessage | str], # multiple turn prompt with media and text-based prompt
3942
]
4043

44+
VeAgent = Union[Agent, RemoteVeAgent, SequentialAgent, ParallelAgent, LoopAgent]
45+
4146

4247
class Runner:
4348
def __init__(
4449
self,
45-
agent: Agent | RemoteVeAgent,
50+
agent: VeAgent,
4651
short_term_memory: ShortTermMemory,
4752
app_name: str = "veadk_default_app",
4853
user_id: str = "veadk_default_user",
@@ -166,10 +171,12 @@ async def run(
166171
return final_output
167172

168173
def save_tracing_file(self, session_id: str) -> str:
169-
if not isinstance(self.agent, Agent):
174+
if not isinstance(
175+
self.agent, (Agent, SequentialAgent, ParallelAgent, LoopAgent)
176+
):
170177
logger.warning(
171178
(
172-
"The agent is not an instance of VeADK Agent, cannot save tracing file."
179+
"The agent is not an instance of Agent, SequentialAgent, ParallelAgent or LoopAgent, cannot save tracing file."
173180
)
174181
)
175182
return ""

veadk/types.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
from pydantic import BaseModel, Field
1616

1717
from veadk.agent import Agent
18+
from veadk.agents.loop_agent import LoopAgent
19+
from veadk.agents.parallel_agent import ParallelAgent
20+
from veadk.agents.sequential_agent import SequentialAgent
1821
from veadk.memory.short_term_memory import ShortTermMemory
1922

2023

@@ -35,7 +38,9 @@ class AgentRunConfig(BaseModel):
3538
default="veadk_vefaas_app", description="The name of the application"
3639
)
3740

38-
agent: Agent = Field(..., description="The root agent instance")
41+
agent: Agent | SequentialAgent | ParallelAgent | LoopAgent = Field(
42+
..., description="The root agent instance"
43+
)
3944

4045
short_term_memory: ShortTermMemory = Field(
4146
default_factory=ShortTermMemory, description="The short-term memory instance"

0 commit comments

Comments
 (0)