A shell agent that runs its sub-agents in parallel in an isolated manner. This approach is beneficial for scenarios requiring multiple perspectives or attempts on a single task, such as: - Running different algorithms simultaneously. - Generating multiple responses for review by a subseque
| 154 | ' Please use Workflow instead.' |
| 155 | ) |
| 156 | class ParallelAgent(BaseAgent): |
| 157 | """A shell agent that runs its sub-agents in parallel in an isolated manner. |
| 158 | |
| 159 | This approach is beneficial for scenarios requiring multiple perspectives or |
| 160 | attempts on a single task, such as: |
| 161 | |
| 162 | - Running different algorithms simultaneously. |
| 163 | - Generating multiple responses for review by a subsequent evaluation agent. |
| 164 | |
| 165 | .. deprecated:: |
| 166 | ParallelAgent is deprecated and will be removed in future versions. |
| 167 | Please use Workflow instead. |
| 168 | """ |
| 169 | |
| 170 | config_type: ClassVar[type[BaseAgentConfig]] = ParallelAgentConfig |
| 171 | """The config type for this agent. |
| 172 | |
| 173 | DEPRECATED: This attribute is deprecated and will be removed in a future |
| 174 | version, along with the AgentConfig YAML loader. |
| 175 | """ |
| 176 | |
| 177 | @override |
| 178 | async def _run_async_impl( |
| 179 | self, ctx: InvocationContext |
| 180 | ) -> AsyncGenerator[Event, None]: |
| 181 | if not self.sub_agents: |
| 182 | return |
| 183 | |
| 184 | agent_state = self._load_agent_state(ctx, BaseAgentState) |
| 185 | if ctx.is_resumable and agent_state is None: |
| 186 | ctx.set_agent_state(self.name, agent_state=BaseAgentState()) |
| 187 | yield self._create_agent_state_event(ctx) |
| 188 | |
| 189 | agent_runs = [] |
| 190 | # Prepare and collect async generators for each sub-agent. |
| 191 | for sub_agent in self.sub_agents: |
| 192 | sub_agent_ctx = _create_branch_ctx_for_sub_agent(self, sub_agent, ctx) |
| 193 | |
| 194 | # Only include sub-agents that haven't finished in a previous run. |
| 195 | if not sub_agent_ctx.end_of_agents.get(sub_agent.name): |
| 196 | agent_runs.append(sub_agent.run_async(sub_agent_ctx)) |
| 197 | |
| 198 | pause_invocation = False |
| 199 | try: |
| 200 | merge_func = ( |
| 201 | _merge_agent_run |
| 202 | if sys.version_info >= (3, 11) |
| 203 | else _merge_agent_run_pre_3_11 |
| 204 | ) |
| 205 | async with Aclosing(merge_func(agent_runs)) as agen: |
| 206 | async for event in agen: |
| 207 | yield event |
| 208 | if ctx.should_pause_invocation(event): |
| 209 | pause_invocation = True |
| 210 | |
| 211 | if pause_invocation: |
| 212 | return |
| 213 |
no outgoing calls