Main entry method to run the agent in this runner. If event compaction is enabled in the App configuration, it will be performed after all agent events for the current invocation have been yielded. The async generator will only finish iterating after event compaction is complete. Ho
(
self,
*,
user_id: str,
session_id: str,
invocation_id: Optional[str] = None,
new_message: Optional[types.Content] = None,
state_delta: Optional[dict[str, Any]] = None,
run_config: Optional[RunConfig] = None,
yield_user_message: bool = False,
)
| 930 | thread.join() |
| 931 | |
| 932 | async def run_async( |
| 933 | self, |
| 934 | *, |
| 935 | user_id: str, |
| 936 | session_id: str, |
| 937 | invocation_id: Optional[str] = None, |
| 938 | new_message: Optional[types.Content] = None, |
| 939 | state_delta: Optional[dict[str, Any]] = None, |
| 940 | run_config: Optional[RunConfig] = None, |
| 941 | yield_user_message: bool = False, |
| 942 | ) -> AsyncGenerator[Event, None]: |
| 943 | """Main entry method to run the agent in this runner. |
| 944 | |
| 945 | If event compaction is enabled in the App configuration, it will be |
| 946 | performed after all agent events for the current invocation have been |
| 947 | yielded. The async generator will only finish iterating after event |
| 948 | compaction is complete. However, this does not block new `run_async` |
| 949 | calls for subsequent user queries, which can be started concurrently. |
| 950 | |
| 951 | Args: |
| 952 | user_id: The user ID of the session. |
| 953 | session_id: The session ID of the session. |
| 954 | invocation_id: The invocation ID of the session, set this to resume an |
| 955 | interrupted invocation. |
| 956 | new_message: A new message to append to the session. |
| 957 | state_delta: Optional state changes to apply to the session. |
| 958 | run_config: The run config for the agent. |
| 959 | yield_user_message: If True, yield the user message event before |
| 960 | agent/node events. |
| 961 | |
| 962 | Yields: |
| 963 | The events generated by the agent. |
| 964 | |
| 965 | Raises: |
| 966 | ValueError: If the session is not found; If both invocation_id and |
| 967 | new_message are None. |
| 968 | """ |
| 969 | run_config = run_config or RunConfig() |
| 970 | |
| 971 | if new_message and not new_message.role: |
| 972 | new_message.role = 'user' |
| 973 | |
| 974 | from .agents.llm_agent import LlmAgent |
| 975 | from .workflow._base_node import BaseNode |
| 976 | |
| 977 | if isinstance(self.agent, LlmAgent): |
| 978 | if self.agent.mode is None: |
| 979 | # LlmAgent as root agent must have chat mode. |
| 980 | self.agent.mode = 'chat' |
| 981 | |
| 982 | if self.agent.mode == 'chat': |
| 983 | session = await self._get_or_create_session( |
| 984 | user_id=user_id, session_id=session_id |
| 985 | ) |
| 986 | # when the chat coordinator has task-mode sub-agents, |
| 987 | # the wrapper handles delegation via ctx.run_node. Don't let |
| 988 | # the legacy sub-agent picker bypass the coordinator on resume. |
| 989 | has_task_subagent = any( |