> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openhands.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# openhands.sdk.event

> API reference for openhands.sdk.event module

### class ActionEvent

Bases: [`LLMConvertibleEvent`](#class-llmconvertibleevent)

#### Properties

* `action`: Action | None
* `critic_result`: CriticResult | None
* `llm_response_id`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `reasoning_content`: str | None
* `responses_reasoning_item`: ReasoningItemModel | None
* `security_risk`: SecurityRisk
* `source`: Literal\['agent', 'user', 'environment']
* `summary`: str | None
* `thinking_blocks`: list\[ThinkingBlock | RedactedThinkingBlock]
* `thought`: Sequence\[TextContent]
* `tool_call`: MessageToolCall
* `tool_call_id`: str
* `tool_name`: str
* `visualize`: Text
  Return Rich Text representation of this action event.

#### Methods

#### to\_llm\_message()

Individual message - may be incomplete for multi-action batches

### class AgentErrorEvent

Bases: [`ObservationBaseEvent`](#class-observationbaseevent)

Error triggered by the agent.

Note: This event should not contain model “thought” or “reasoning\_content”. It
represents an error produced by the agent/scaffold, not model output.

#### Properties

* `error`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `visualize`: Text
  Return Rich Text representation of this agent error event.

#### Methods

#### to\_llm\_message()

### class Condensation

Bases: [`Event`](#class-event)

This action indicates a condensation of the conversation history is happening.

#### Properties

* `forgotten_event_ids`: list\[[EventID](#class-eventid)]
* `has_summary_metadata`: bool
  Checks if both summary and summary\_offset are present.
* `llm_response_id`: [EventID](#class-eventid)
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: SourceType
* `summary`: str | None
* `summary_event`: [CondensationSummaryEvent](#class-condensationsummaryevent)
  Generates a CondensationSummaryEvent.
  Since summary events are not part of the main event store and are generated
  dynamically, this property ensures the created event has a unique and consistent
  ID based on the condensation event’s ID.
  * Raises:
    `ValueError` – If no summary is present.
* `summary_offset`: int | None
* `visualize`: Text
  Return Rich Text representation of this event.
  This is a fallback implementation for unknown event types.
  Subclasses should override this method to provide specific visualization.

#### Methods

#### apply()

Applies the condensation to a list of events.

This method removes events that are marked to be forgotten and returns a new
list of events. If the summary metadata is present (both summary and offset),
the corresponding CondensationSummaryEvent will be inserted at the specified
offset *after* the forgotten events have been removed.

### class CondensationRequest

Bases: [`Event`](#class-event)

This action is used to request a condensation of the conversation history.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: SourceType
* `visualize`: Text
  Return Rich Text representation of this event.
  This is a fallback implementation for unknown event types.
  Subclasses should override this method to provide specific visualization.

#### Methods

#### action

The action type, namely ActionType.CONDENSATION\_REQUEST.

* Type:
  str

### class CondensationSummaryEvent

Bases: [`LLMConvertibleEvent`](#class-llmconvertibleevent)

This event represents a summary generated by a condenser.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: SourceType
* `summary`: str
  The summary text.

#### Methods

#### to\_llm\_message()

### class ConversationStateUpdateEvent

Bases: [`Event`](#class-event)

Event that contains conversation state updates.

This event is sent via websocket whenever the conversation state changes,
allowing remote clients to stay in sync without making REST API calls.

All fields are serialized versions of the corresponding ConversationState fields
to ensure compatibility with websocket transmission.

#### Properties

* `key`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `value`: Any

#### Methods

#### classmethod from\_conversation\_state()

Create a state update event from a ConversationState object.

This creates an event containing a snapshot of important state fields.

* Parameters:
  * `state` – The ConversationState to serialize
  * `conversation_id` – The conversation ID for the event
* Returns:
  A ConversationStateUpdateEvent with serialized state data

#### classmethod validate\_key()

#### classmethod validate\_value()

### class Event

Bases: `DiscriminatedUnionMixin`, `ABC`

Base class for all events.

#### Properties

* `id`: str
* `model_config`: ClassVar\[ConfigDict] = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `timestamp`: str
* `visualize`: Text
  Return Rich Text representation of this event.
  This is a fallback implementation for unknown event types.
  Subclasses should override this method to provide specific visualization.

### class LLMCompletionLogEvent

Bases: [`Event`](#class-event)

Event containing LLM completion log data.

When an LLM is configured with log\_completions=True in a remote conversation,
this event streams the completion log data back to the client through WebSocket
instead of writing it to a file inside the Docker container.

#### Properties

* `filename`: str
* `log_data`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `model_name`: str
* `source`: Literal\['agent', 'user', 'environment']
* `usage_id`: str

### class LLMConvertibleEvent

Bases: [`Event`](#class-event), `ABC`

Base class for events that can be converted to LLM messages.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].

#### Methods

#### static events\_to\_messages()

Convert event stream to LLM message stream, handling multi-action batches

#### abstractmethod to\_llm\_message()

### class MessageEvent

Bases: [`LLMConvertibleEvent`](#class-llmconvertibleevent)

Message from either agent or user.

This is originally the “MessageAction”, but it suppose not to be tool call.

#### Properties

* `activated_skills`: list\[str]
* `critic_result`: CriticResult | None
* `extended_content`: list\[TextContent]
* `llm_message`: Message
* `llm_response_id`: str | None
* `model_config`: ClassVar\[ConfigDict] = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `reasoning_content`: str
* `sender`: str | None
* `source`: Literal\['agent', 'user', 'environment']
* `thinking_blocks`: Sequence\[ThinkingBlock | RedactedThinkingBlock]
  Return the Anthropic thinking blocks from the LLM message.
* `visualize`: Text
  Return Rich Text representation of this message event.

#### Methods

#### to\_llm\_message()

### class ObservationBaseEvent

Bases: [`LLMConvertibleEvent`](#class-llmconvertibleevent)

Base class for anything as a response to a tool call.

Examples include tool execution, error, user reject.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `tool_call_id`: str
* `tool_name`: str

### class ObservationEvent

Bases: [`ObservationBaseEvent`](#class-observationbaseevent)

#### Properties

* `action_id`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `observation`: Observation
* `visualize`: Text
  Return Rich Text representation of this observation event.

#### Methods

#### to\_llm\_message()

### class PauseEvent

Bases: [`Event`](#class-event)

Event indicating that the agent execution was paused by user request.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `visualize`: Text
  Return Rich Text representation of this pause event.

### class SystemPromptEvent

Bases: [`LLMConvertibleEvent`](#class-llmconvertibleevent)

System prompt added by the agent.

The system prompt can optionally include dynamic context that varies between
conversations. When `dynamic_context` is provided, it is included as a
second content block in the same system message. Cache markers are NOT
applied here - they are applied by `LLM._apply_prompt_caching()` when
caching is enabled, ensuring provider-specific cache control is only added
when appropriate.

#### Properties

* `dynamic_context`: TextContent | None
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `source`: Literal\['agent', 'user', 'environment']
* `system_prompt`: TextContent
* `tools`: list\[ToolDefinition]
* `visualize`: Text
  Return Rich Text representation of this system prompt event.

#### Methods

#### system\_prompt

The static system prompt text (cacheable across conversations)

* Type:
  openhands.sdk.llm.message.TextContent

#### tools

List of available tools

* Type:
  list\[openhands.sdk.tool.tool.ToolDefinition]

#### dynamic\_context

Optional per-conversation context (hosts, repo info, etc.)
Sent as a second TextContent block inside the system message.

* Type:
  openhands.sdk.llm.message.TextContent | None

#### to\_llm\_message()

Convert to a single system LLM message.

When `dynamic_context` is present the message contains two content
blocks: the static prompt followed by the dynamic context. Cache markers
are NOT applied here - they are applied by `LLM._apply_prompt_caching()`
when caching is enabled, which marks the static block (index 0) and leaves
the dynamic block (index 1) unmarked for cross-conversation cache sharing.

### class TokenEvent

Bases: [`Event`](#class-event)

Event from VLLM representing token IDs used in LLM interaction.

#### Properties

* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `prompt_token_ids`: list\[int]
* `response_token_ids`: list\[int]
* `source`: Literal\['agent', 'user', 'environment']

### class UserRejectObservation

Bases: [`ObservationBaseEvent`](#class-observationbaseevent)

Observation when an action is rejected by user or hook.

This event is emitted when:

* User rejects an action during confirmation mode (rejection\_source=”user”)
* A PreToolUse hook blocks an action (rejection\_source=”hook”)

#### Properties

* `action_id`: str
* `model_config`: = (configuration object)
  Configuration for the model, should be a dictionary conforming to \[ConfigDict]\[pydantic.config.ConfigDict].
* `rejection_reason`: str
* `rejection_source`: Literal\['user', 'hook']
* `visualize`: Text
  Return Rich Text representation of this user rejection event.

#### Methods

#### to\_llm\_message()
