Skip to main content
Every agent yields a stream of unified Event objects. All events share the same Event class and are distinguished by their type field using the EventType enum.

EventType values

EventTypeWhen emittedDescription
USER_MESSAGEUser input persisted by RunnerThe user’s message at the start of a turn
AGENT_MESSAGEAgent responseFinal answers, thoughts, tool call requests, or partial streaming chunks
TOOL_RESPONSETool execution resultThe result returned by a tool after execution
AGENT_STARTStart of astream()Marks the beginning of an agent’s execution
AGENT_ENDEnd of astream()Marks the end of an agent’s execution

Convenience properties

PropertyTypeDescription
event.textstrConcatenated text from all text parts in the event’s content
event.datadict | NoneFirst data part’s dict, or None
event.tool_namestr | NoneName of the tool (for TOOL_RESPONSE events)
event.tool_inputdict | NoneInput arguments passed to the tool
event.tool_callslist[dict]List of tool call requests from the LLM response
event.has_tool_callsboolTrue if the event contains tool call requests
event.errorstr | NoneError message, if the event represents an error

Key methods

MethodDescription
event.is_final_response()Returns True if this is the agent’s final answer (an AGENT_MESSAGE with no tool calls and not a partial streaming chunk)
event.to_langchain_message()Converts the event to the corresponding LangChain message type (HumanMessage, AIMessage, ToolMessage, etc.)
Event.from_langchain_message(msg)Class method that creates an Event from a LangChain message

Checking event types

Use the EventType enum and convenience methods instead of isinstance checks:
from langchain_adk.events.event import Event, EventType

# Check for final response (replaces isinstance(event, FinalAnswerEvent))
if event.is_final_response():
    print(event.text)

# Check for tool calls (replaces isinstance(event, ToolCallEvent))
if event.has_tool_calls:
    for tc in event.tool_calls:
        print(f"Calling {tc['name']} with {tc['args']}")

# Check for tool results (replaces isinstance(event, ToolResultEvent))
if event.type == EventType.TOOL_RESPONSE:
    print(f"{event.tool_name} returned: {event.text}")

# Check for agent lifecycle
if event.type == EventType.AGENT_START:
    print(f"Agent {event.agent_name} starting")

Metadata conventions

Events use the metadata dict for additional context. Common keys:
KeyDescription
react_stepThe ReAct loop iteration number
errorError message string when something went wrong
exception_typeThe Python exception class name (e.g. "ValueError")
scratchpadInternal reasoning or planning notes from the agent

EventActions

Events carry EventActions for side-effects:
class EventActions(BaseModel):
    state_delta: dict[str, Any] = {}     # merged into session state
    transfer_to_agent: str | None = None # trigger agent handoff
    escalate: bool | None = None         # stop parent LoopAgent
    skip_summarization: bool | None = None
    end_of_agent: bool | None = None
    compaction: EventCompaction | None = None

LlmResponse

AGENT_MESSAGE events may carry an llm_response: LlmResponse field with token usage and model version:
event.llm_response.input_tokens
event.llm_response.output_tokens
event.llm_response.model_version