Skip to main content

class BaseConversation

Bases: ABC Abstract base class for conversation implementations. This class defines the interface that all conversation implementations must follow. Conversations manage the interaction between users and agents, handling message exchange, execution control, and state management.

Properties

  • id: ConversationID
  • state: ConversationStateProtocol
  • conversation_stats: ConversationStats
  • confirmation_policy_active: bool
  • is_confirmation_mode_active: bool Check if confirmation mode is active.
Returns True if BOTH conditions are met:
  1. The conversation state has a security analyzer set (not None)
  2. The confirmation policy is active

Methods

init() -> None source Initialize the base conversation with span tracking. abstractmethod send_message() -> None source Send a message to the agent. Parameters:
  • message str | Message – Either a string (which will be converted to a user message) or a Message object
  • sender str | None – Optional identifier of the sender. Can be used to track message origin in multi-agent scenarios. For example, when one agent delegates to another, the sender can be set to identify which agent is sending the message.
    message
    str | Message
    required
    None
    sender
    str | None
    None
abstractmethod run() -> None source Execute the agent to process messages and perform actions. This method runs the agent until it finishes processing the current message or reaches the maximum iteration limit. abstractmethod set_confirmation_policy() -> None source Set the confirmation policy for the conversation.
policy
ConfirmationPolicyBase
required
None
abstractmethod set_security_analyzer() -> None source Set the security analyzer for the conversation.
analyzer
SecurityAnalyzerBase | None
required
None
abstractmethod reject_pending_actions() -> None source
reason
str
None
abstractmethod pause() -> None source abstractmethod update_secrets() -> None source
secrets
Mapping[str, SecretValue]
required
None
abstractmethod close() -> None source abstractmethod generate_title() -> str source Generate a title for the conversation based on the first user message. Parameters:
  • llm LLM | None – Optional LLM to use for title generation. If not provided, uses the agent’s LLM.
  • max_length int – Maximum length of the generated title.
Returns:
  • str A generated title for the conversation.
Raises:
  • ValueError – If no user messages are found in the conversation.
    llm
    LLM | None
    None
    max_length
    int
    None
get_persistence_dir() -> str source Get the persistence directory for the conversation. Parameters:
  • persistence_base_dir str | Path – Base directory for persistence. Can be a string path or Path object.
  • conversation_id ConversationID – Unique conversation ID.
Returns:
  • str String path to the conversation-specific persistence directory.
  • str Always returns a normalized string path even if a Path was provided.
    persistence_base_dir
    str | Path
    required
    None
    conversation_id
    ConversationID
    required
    None
abstractmethod ask_agent() -> str source Ask the agent a simple, stateless question and get a direct LLM response. This bypasses the normal conversation flow and does not modify, persist, or become part of the conversation state. The request is not remembered by the main agent, no events are recorded, and execution status is untouched. It is also thread-safe and may be called while conversation.run() is executing in another thread. Parameters:
  • question str – A simple string question to ask the agent
Returns:
  • str A string response from the agent
    question
    str
    required
    None
abstractmethod condense() -> None source Force condensation of the conversation history. This method uses the existing condensation request pattern to trigger condensation. It adds a CondensationRequest event to the conversation and forces the agent to take a single step to process it. The condensation will be applied immediately and will modify the conversation state by adding a condensation event to the history. Raises:
  • ValueError – If no condenser is configured or the condenser doesn’t handle condensation requests.
abstractmethod execute_tool() -> Observation source Execute a tool directly without going through the agent loop. This method allows executing tools before or outside of the normal conversation.run() flow. It handles agent initialization automatically, so tools can be executed before the first run() call. Note: This method bypasses the agent loop, including confirmation policies and security analyzer checks. Callers are responsible for applying any safeguards before executing potentially destructive tools. This is useful for:
  • Pre-run setup operations (e.g., indexing repositories)
  • Manual tool execution for environment setup
  • Testing tool behavior outside the agent loop
Parameters:
  • tool_name str – The name of the tool to execute (e.g., “sleeptime_compute”)
  • action Action – The action to pass to the tool executor
Returns:
  • Observation The observation returned by the tool execution
Raises:
  • KeyError – If the tool is not found in the agent’s tools
  • NotImplementedError – If the tool has no executor
    tool_name
    str
    required
    None
    action
    Action
    required
    None
compose_callbacks() -> CallbackType source Compose multiple callbacks into a single callback function. Parameters:
  • callbacks Iterable[CallbackType] – An iterable of callback functions
Returns:
  • CallbackType A single callback function that calls all provided callbacks
    callbacks
    Iterable[CallbackType]
    required
    None

class Conversation

Factory class for creating conversation instances with OpenHands agents. This factory automatically creates either a LocalConversation or RemoteConversation based on the workspace type provided. LocalConversation runs the agent locally, while RemoteConversation connects to a remote agent server. Returns:
  • LocalConversation if workspace is local, RemoteConversation if workspace
  • is remote.

class EventLog

Bases: EventsListBase Persistent event log with locking for concurrent writes. This class provides thread-safe and process-safe event storage using the FileStore’s locking mechanism. Events are persisted to disk and can be accessed by index or event ID.

Methods

init() -> None source
fs
FileStore
required
None
dir_path
str
None
get_index() -> int source Return the integer index for a given event_id.
event_id
EventID
required
None
get_id() -> EventID source Return the event_id for a given index.
idx
int
required
None
append() -> None source Append an event with locking for thread/process safety. Raises:
  • TimeoutError – If the lock cannot be acquired within LOCK_TIMEOUT_SECONDS.
  • ValueError – If an event with the same ID already exists.
    event
    Event
    required
    None

class EventsListBase

Bases: Sequence[Event], ABC Abstract base class for event lists that can be appended to. This provides a common interface for both local EventLog and remote RemoteEventsList implementations, avoiding circular imports in protocols.

Methods

abstractmethod append() -> None source Add a new event to the list.
event
Event
required
None

class WebSocketConnectionError

Bases: RuntimeError Raised when WebSocket connection fails to establish within the timeout.

Properties

  • conversation_id
  • timeout

Methods

init() -> None source
conversation_id
ConversationID
required
None
timeout
float
required
None
message
str | None
None

class LocalConversation

Bases: BaseConversation

Properties

  • agent: AgentBase
  • workspace: LocalWorkspace
  • max_iteration_per_run: int
  • llm_registry: LLMRegistry
  • delete_on_close: bool
  • id: ConversationID Get the unique ID of the conversation.
  • state: ConversationState Get the conversation state.
It returns a protocol that has a subset of ConversationState methods and properties. We will have the ability to access the same properties of ConversationState on a remote conversation object. But we won’t be able to access methods that mutate the state.
  • conversation_stats
  • stuck_detector: StuckDetector | None Get the stuck detector instance if enabled.
  • resolved_plugins: list[ResolvedPluginSource] | None Get the resolved plugin sources after plugins are loaded.
Returns None if plugins haven’t been loaded yet, or if no plugins were specified. Use this for persistence to ensure conversation resume uses the exact same plugin versions.

Methods

init() source Initialize the conversation. Parameters:
  • agent AgentBase – The agent to use for the conversation.
  • workspace str | Path | LocalWorkspace – Working directory for agent operations and tool execution. Can be a string path, Path object, or LocalWorkspace instance.
  • plugins list[PluginSource] | None – Optional list of plugins to load. Each plugin is specified with a source (github:owner/repo, git URL, or local path), optional ref (branch/tag/commit), and optional repo_path for monorepos. Plugins are loaded in order with these merge semantics: skills override by name (last wins), MCP config override by key (last wins), hooks concatenate (all run).
  • persistence_dir str | Path | None – Directory for persisting conversation state and events. Can be a string path or Path object.
  • conversation_id ConversationID | None – Optional ID for the conversation. If provided, will be used to identify the conversation. The user might want to suffix their persistent filestore with this ID.
  • callbacks list[ConversationCallbackType] | None – Optional list of callback functions to handle events
  • token_callbacks list[ConversationTokenCallbackType] | None – Optional list of callbacks invoked for streaming deltas
  • hook_config HookConfig | None – Optional hook configuration to auto-wire session hooks. If plugins are loaded, their hooks are combined with this config.
  • max_iteration_per_run int – Maximum number of iterations per run
  • visualizer type[ConversationVisualizerBase] | ConversationVisualizerBase | None – Visualization configuration. Can be:
    • ConversationVisualizerBase subclass: Class to instantiate (default: ConversationVisualizer)
    • ConversationVisualizerBase instance: Use custom visualizer
    • None: No visualization
  • stuck_detection bool – Whether to enable stuck detection
  • stuck_detection_thresholds StuckDetectionThresholds | Mapping[str, int] | None – Optional configuration for stuck detection thresholds. Can be a StuckDetectionThresholds instance or a dict with keys: ‘action_observation’, ‘action_error’, ‘monologue’, ‘alternating_pattern’. Values are integers representing the number of repetitions before triggering.
  • cipher Cipher | None – Optional cipher for encrypting/decrypting secrets in persisted state. If provided, secrets are encrypted when saving and decrypted when loading. If not provided, secrets are redacted (lost) on serialization.
    agent
    AgentBase
    required
    None
    workspace
    str | Path | LocalWorkspace
    required
    None
    plugins
    list[PluginSource] | None
    None
    persistence_dir
    str | Path | None
    None
    conversation_id
    ConversationID | None
    None
    callbacks
    list[ConversationCallbackType] | None
    None
    token_callbacks
    list[ConversationTokenCallbackType] | None
    None
    hook_config
    HookConfig | None
    None
    max_iteration_per_run
    int
    None
    stuck_detection
    bool
    None
    stuck_detection_thresholds
    StuckDetectionThresholds | Mapping[str, int] | None
    None
    visualizer
    type[ConversationVisualizerBase] | ConversationVisualizerBase | None
    None
    secrets
    Mapping[str, SecretValue] | None
    None
    delete_on_close
    bool
    None
    cipher
    Cipher | None
    None
    _
    object
    None
send_message() -> None source Send a message to the agent. Parameters:
  • message str | Message – Either a string (which will be converted to a user message) or a Message object
  • sender str | None – Optional identifier of the sender. Can be used to track message origin in multi-agent scenarios. For example, when one agent delegates to another, the sender can be set to identify which agent is sending the message.
    message
    str | Message
    required
    None
    sender
    str | None
    None
run() -> None source Runs the conversation until the agent finishes. In confirmation mode:
  • First call: creates actions but doesn’t execute them, stops and waits
  • Second call: executes pending actions (implicit confirmation)
In normal mode:
  • Creates and executes actions immediately
Can be paused between steps set_confirmation_policy() -> None source Set the confirmation policy and store it in conversation state.
policy
ConfirmationPolicyBase
required
None
reject_pending_actions() -> None source Reject all pending actions from the agent. This is a non-invasive method to reject actions between run() calls. Also clears the agent_waiting_for_confirmation flag.
reason
str
None
pause() -> None source Pause agent execution. This method can be called from any thread to request that the agent pause execution. The pause will take effect at the next iteration of the run loop (between agent steps). Note: If called during an LLM completion, the pause will not take effect until the current LLM call completes. update_secrets() -> None source Add secrets to the conversation. Parameters:
  • secrets Mapping[str, SecretValue] – Dictionary mapping secret keys to values or no-arg callables. SecretValue = str | Callable[[], str]. Callables are invoked lazily when a command references the secret key.
    secrets
    Mapping[str, SecretValue]
    required
    None
set_security_analyzer() -> None source Set the security analyzer for the conversation.
analyzer
SecurityAnalyzerBase | None
required
None
close() -> None source Close the conversation and clean up all tool executors. ask_agent() -> str source Ask the agent a simple, stateless question and get a direct LLM response. This bypasses the normal conversation flow and does not modify, persist, or become part of the conversation state. The request is not remembered by the main agent, no events are recorded, and execution status is untouched. It is also thread-safe and may be called while conversation.run() is executing in another thread. Parameters:
  • question str – A simple string question to ask the agent
Returns:
  • str A string response from the agent
    question
    str
    required
    None
generate_title() -> str source Generate a title for the conversation based on the first user message. Parameters:
  • llm LLM | None – Optional LLM to use for title generation. If not provided, uses self.agent.llm.
  • max_length int – Maximum length of the generated title.
Returns:
  • str A generated title for the conversation.
Raises:
  • ValueError – If no user messages are found in the conversation.
    llm
    LLM | None
    None
    max_length
    int
    None
condense() -> None source Synchronously force condense the conversation history. If the agent is currently running, condense() will wait for the ongoing step to finish before proceeding. Raises ValueError if no compatible condenser exists. execute_tool() -> Observation source Execute a tool directly without going through the agent loop. This method allows executing tools before or outside of the normal conversation.run() flow. It handles agent initialization automatically, so tools can be executed before the first run() call. Note: This method bypasses the agent loop, including confirmation policies and security analyzer checks. Callers are responsible for applying any safeguards before executing potentially destructive tools. This is useful for:
  • Pre-run setup operations (e.g., indexing repositories)
  • Manual tool execution for environment setup
  • Testing tool behavior outside the agent loop
Parameters:
  • tool_name str – The name of the tool to execute (e.g., “sleeptime_compute”)
  • action Action – The action to pass to the tool executor
Returns:
  • Observation The observation returned by the tool execution
Raises:
  • KeyError – If the tool is not found in the agent’s tools
  • NotImplementedError – If the tool has no executor
    tool_name
    str
    required
    None
    action
    Action
    required
    None

class RemoteConversation

Bases: BaseConversation

Properties

  • agent: AgentBase
  • max_iteration_per_run: int
  • workspace: RemoteWorkspace
  • delete_on_close: bool
  • id: ConversationID
  • state: RemoteState Access to remote conversation state.
  • conversation_stats
  • stuck_detector Stuck detector for compatibility. Not implemented for remote conversations.

Methods

init() -> None source Remote conversation proxy that talks to an agent server. Parameters:
  • agent AgentBase – Agent configuration (will be sent to the server)
  • workspace RemoteWorkspace – The working directory for agent operations and tool execution.
  • plugins list | None – Optional list of plugins to load on the server. Each plugin is a PluginSource specifying source, ref, and repo_path.
  • conversation_id ConversationID | None – Optional existing conversation id to attach to
  • callbacks list[ConversationCallbackType] | None – Optional callbacks to receive events (not yet streamed)
  • max_iteration_per_run int – Max iterations configured on server
  • stuck_detection bool – Whether to enable stuck detection on server
  • stuck_detection_thresholds StuckDetectionThresholds | Mapping[str, int] | None – Optional configuration for stuck detection thresholds. Can be a StuckDetectionThresholds instance or a dict with keys: ‘action_observation’, ‘action_error’, ‘monologue’, ‘alternating_pattern’. Values are integers representing the number of repetitions before triggering.
  • hook_config HookConfig | None – Optional hook configuration for session hooks
  • visualizer type[ConversationVisualizerBase] | ConversationVisualizerBase | None – Visualization configuration. Can be:
    • ConversationVisualizerBase subclass: Class to instantiate (default: ConversationVisualizer)
    • ConversationVisualizerBase instance: Use custom visualizer
    • None: No visualization
  • secrets Mapping[str, SecretValue] | None – Optional secrets to initialize the conversation with
    agent
    AgentBase
    required
    None
    workspace
    RemoteWorkspace
    required
    None
    plugins
    list | None
    None
    conversation_id
    ConversationID | None
    None
    callbacks
    list[ConversationCallbackType] | None
    None
    max_iteration_per_run
    int
    None
    stuck_detection
    bool
    None
    stuck_detection_thresholds
    StuckDetectionThresholds | Mapping[str, int] | None
    None
    hook_config
    HookConfig | None
    None
    visualizer
    type[ConversationVisualizerBase] | ConversationVisualizerBase | None
    None
    secrets
    Mapping[str, SecretValue] | None
    None
    delete_on_close
    bool
    None
    _
    object
    None
send_message() -> None source
message
str | Message
required
None
sender
str | None
None
run() -> None source Trigger a run on the server. Parameters:
  • blocking bool – If True (default), wait for the run to complete by polling the server. If False, return immediately after triggering the run.
  • poll_interval float – Time in seconds between status polls (only used when blocking=True). Default is 1.0 second.
  • timeout float – Maximum time in seconds to wait for the run to complete (only used when blocking=True). Default is 3600 seconds.
Raises:
  • ConversationRunError – If the run fails or times out.
    blocking
    bool
    None
    poll_interval
    float
    None
    timeout
    float
    None
set_confirmation_policy() -> None source
policy
ConfirmationPolicyBase
required
None
set_security_analyzer() -> None source Set the security analyzer for the remote conversation.
analyzer
SecurityAnalyzerBase | None
required
None
reject_pending_actions() -> None source
reason
str
None
pause() -> None source update_secrets() -> None source
secrets
Mapping[str, SecretValue]
required
None
ask_agent() -> str source Ask the agent a simple, stateless question and get a direct LLM response. This bypasses the normal conversation flow and does not modify, persist, or become part of the conversation state. The request is not remembered by the main agent, no events are recorded, and execution status is untouched. It is also thread-safe and may be called while conversation.run() is executing in another thread. Parameters:
  • question str – A simple string question to ask the agent
Returns:
  • str A string response from the agent
    question
    str
    required
    None
generate_title() -> str source Generate a title for the conversation based on the first user message. Parameters:
  • llm LLM | None – Optional LLM to use for title generation. If provided, its usage_id will be sent to the server. If not provided, uses the agent’s LLM.
  • max_length int – Maximum length of the generated title.
Returns:
  • str A generated title for the conversation.
    llm
    LLM | None
    None
    max_length
    int
    None
condense() -> None source Force condensation of the conversation history. This method sends a condensation request to the remote agent server. The server will use the existing condensation request pattern to trigger condensation if a condenser is configured and handles condensation requests. The condensation will be applied on the server side and will modify the conversation state by adding a condensation event to the history. Raises:
  • HTTPError – If the server returns an error (e.g., no condenser configured).
execute_tool() -> Observation source Execute a tool directly without going through the agent loop. Note: This method is not yet supported for RemoteConversation. Tool execution for remote conversations happens on the server side during the normal agent loop. Parameters:
  • tool_name str – The name of the tool to execute
  • action Action – The action to pass to the tool executor
Raises:
  • NotImplementedError – Always, as this feature is not yet supported for remote conversations.
    tool_name
    str
    required
    None
    action
    Action
    required
    None
close() -> None source Close the conversation and clean up resources. Note: We don’t close self._client here because it’s shared with the workspace. The workspace owns the client and will close it during its own cleanup. Closing it here would prevent the workspace from making cleanup API calls. get_agent_final_response() -> str source Extract the final response from the agent. An agent can end a conversation in two ways:
  1. By calling the finish tool
  2. By returning a text message with no tool calls
Parameters:
  • events Sequence[Event] – List of conversation events to search through.
Returns:
  • str The final response message from the agent, or empty string if not found.
    events
    Sequence[Event]
    required
    None

class SecretRegistry

Bases: OpenHandsModel Manages secrets and injects them into bash commands when needed. The secret registry stores a mapping of secret keys to SecretSources that retrieve the actual secret values. When a bash command is about to be executed, it scans the command for any secret keys and injects the corresponding environment variables. Secret sources will redact / encrypt their sensitive values as appropriate when serializing, depending on the content of the context. If a context is present and contains a ‘cipher’ object, this is used for encryption. If it contains a boolean ‘expose_secrets’ flag set to True, secrets are dunped in plain text. Otherwise secrets are redacted. Additionally, it tracks the latest exported values to enable consistent masking even when callable secrets fail on subsequent calls.

Properties

  • secret_sources: dict[str, SecretSource]

Methods

update_secrets() -> None source Add or update secrets in the manager. Parameters:
  • secrets Mapping[str, SecretValue] – Dictionary mapping secret keys to either string values or callable functions that return string values
    secrets
    Mapping[str, SecretValue]
    required
    None
find_secrets_in_text() -> set[str] source Find all secret keys mentioned in the given text. Parameters:
  • text str – The text to search for secret keys
Returns:
  • set[str] Set of secret keys found in the text
    text
    str
    required
    None
get_secrets_as_env_vars() -> dict[str, str] source Get secrets that should be exported as environment variables for a command. Parameters:
  • command str – The bash command to check for secret references
Returns:
  • dict[str, str] Dictionary of environment variables to export (key -> value)
    command
    str
    required
    None
mask_secrets_in_output() -> str source Mask secret values in the given text. This method uses both the current exported values and attempts to get fresh values from callables to ensure comprehensive masking. Parameters:
  • text str – The text to mask secrets in
Returns:
  • str Text with secret values replaced by <secret-hidden>
    text
    str
    required
    None

class ConversationExecutionStatus

Bases: str, Enum Enum representing the current execution state of the conversation.

Properties

  • IDLE
  • RUNNING
  • PAUSED
  • WAITING_FOR_CONFIRMATION
  • FINISHED
  • ERROR
  • STUCK
  • DELETING

Methods

is_terminal() -> bool source Check if this status represents a terminal state. Terminal states indicate the run has completed and the agent is no longer actively processing. These are: FINISHED, ERROR, STUCK. Note: IDLE is NOT a terminal state - it’s the initial state of a conversation before any run has started. Including IDLE would cause false positives when the WebSocket delivers the initial state update during connection. Returns:
  • bool True if this is a terminal status, False otherwise.

class ConversationState

Bases: OpenHandsModel

Properties

  • id: ConversationID Unique conversation ID
  • agent: AgentBase The agent running in the conversation. This is persisted to allow resuming conversations and check agent configuration to handle e.g., tool changes, LLM changes, etc.
  • workspace: BaseWorkspace Workspace used by the agent to execute commands and read/write files. Not the process working directory.
  • persistence_dir: str | None Directory for persisting conversation state and events. If None, conversation will not be persisted.
  • max_iterations: int Maximum number of iterations the agent can perform in a single run.
  • stuck_detection: bool Whether to enable stuck detection for the agent.
  • execution_status: ConversationExecutionStatus
  • confirmation_policy: ConfirmationPolicyBase
  • security_analyzer: SecurityAnalyzerBase | None Optional security analyzer to evaluate action risks.
  • activated_knowledge_skills: list[str] List of activated knowledge skills name
  • blocked_actions: dict[str, str] Actions blocked by PreToolUse hooks, keyed by action ID
  • blocked_messages: dict[str, str] Messages blocked by UserPromptSubmit hooks, keyed by message ID
  • stats: ConversationStats Conversation statistics for tracking LLM metrics
  • secret_registry: SecretRegistry Registry for handling secrets and sensitive data
  • events: EventLog
  • env_observation_persistence_dir: str | None Directory for persisting environment observation files.

Methods

set_on_state_change() -> None source Set a callback to be called when state changes. Parameters:
  • callback ConversationCallbackType | None – A function that takes an Event (ConversationStateUpdateEvent) or None to remove the callback
    callback
    ConversationCallbackType | None
    required
    None
create() -> ConversationState source Create a new conversation state or resume from persistence. This factory method handles both new conversation creation and resumption from persisted state. New conversation: The provided Agent is used directly. Pydantic validation happens via the cls() constructor. Restored conversation: The provided Agent is validated against the persisted agent using agent.load(). Tools must match (they may have been used in conversation history), but all other configuration can be freely changed: LLM, agent_context, condenser, system prompts, etc. Parameters:
  • id ConversationID – Unique conversation identifier
  • agent AgentBase – The Agent to use (tools must match persisted on restore)
  • workspace BaseWorkspace – Working directory for agent operations
  • persistence_dir str | None – Directory for persisting state and events
  • max_iterations int – Maximum iterations per run
  • stuck_detection bool – Whether to enable stuck detection
  • cipher Cipher | None – Optional cipher for encrypting/decrypting secrets in persisted state. If provided, secrets are encrypted when saving and decrypted when loading. If not provided, secrets are redacted (lost) on serialization.
Returns:
  • ConversationState ConversationState ready for use
Raises:
  • ValueError – If conversation ID or tools mismatch on restore
  • ValidationError – If agent or other fields fail Pydantic validation
    id
    ConversationID
    required
    None
    agent
    AgentBase
    required
    None
    workspace
    BaseWorkspace
    required
    None
    persistence_dir
    str | None
    None
    max_iterations
    int
    None
    stuck_detection
    bool
    None
    cipher
    Cipher | None
    None
block_action() -> None source Persistently record a hook-blocked action.
action_id
str
required
None
reason
str
required
None
pop_blocked_action() -> str | None source Remove and return a hook-blocked action reason, if present.
action_id
str
required
None
block_message() -> None source Persistently record a hook-blocked user message.
message_id
str
required
None
reason
str
required
None
pop_blocked_message() -> str | None source Remove and return a hook-blocked message reason, if present.
message_id
str
required
None
get_unmatched_actions() -> list[ActionEvent] source Find actions in the event history that don’t have matching observations. This method identifies ActionEvents that don’t have corresponding ObservationEvents or UserRejectObservations, which typically indicates actions that are pending confirmation or execution. Parameters:
  • events Sequence[Event] – List of events to search through
Returns:
  • list[ActionEvent] List of ActionEvent objects that don’t have corresponding observations,
  • list[ActionEvent] in chronological order
    events
    Sequence[Event]
    required
    None
acquire() -> bool source Acquire the lock. Parameters:
  • blocking bool – If True, block until lock is acquired. If False, return immediately.
  • timeout float – Maximum time to wait for lock (ignored if blocking=False). -1 means wait indefinitely.
Returns:
  • bool True if lock was acquired, False otherwise.
    blocking
    bool
    None
    timeout
    float
    None
release() -> None source Release the lock. Raises:
  • RuntimeError – If the current thread doesn’t own the lock.
locked() -> bool source Return True if the lock is currently held by any thread. owned() -> bool source Return True if the lock is currently held by the calling thread.

class StuckDetector

Detects when an agent is stuck in repetitive or unproductive patterns. This detector analyzes the conversation history to identify various stuck patterns:
  1. Repeating action-observation cycles
  2. Repeating action-error cycles
  3. Agent monologue (repeated messages without user input)
  4. Repeating alternating action-observation patterns
  5. Context window errors indicating memory issues

Properties

  • state: ConversationState
  • thresholds: StuckDetectionThresholds
  • action_observation_threshold: int
  • action_error_threshold: int
  • monologue_threshold: int
  • alternating_pattern_threshold: int

Methods

init() source
state
ConversationState
required
None
thresholds
StuckDetectionThresholds | None
None
is_stuck() -> bool source Check if the agent is currently stuck. Note: To avoid materializing potentially large file-backed event histories, only the last MAX_EVENTS_TO_SCAN_FOR_STUCK_DETECTION events are analyzed. If a user message exists within this window, only events after it are checked. Otherwise, all events in the window are analyzed.

class ConversationVisualizerBase

Bases: ABC Base class for conversation visualizers. This abstract base class defines the interface that all conversation visualizers must implement. Visualizers can be created before the Conversation is initialized and will be configured with the conversation state automatically. The typical usage pattern:
  1. Create a visualizer instance: viz = MyVisualizer()
  2. Pass it to Conversation: conv = Conversation(agent, visualizer=viz)
  3. Conversation automatically calls viz.initialize(state) to attach the state
You can also pass the uninstantiated class if you don’t need extra args for initialization, and Conversation will create it: conv = Conversation(agent, visualizer=MyVisualizer) Conversation will then calls MyVisualizer() followed by initialize(state)

Properties

  • conversation_stats: ConversationStats | None Get conversation stats from the state.

Methods

init() source Initialize the visualizer base. initialize() -> None source Initialize the visualizer with conversation state. This method is called by Conversation after the state is created, allowing the visualizer to access conversation stats and other state information. Subclasses should not override this method, to ensure the state is set. Parameters:
  • state ConversationStateProtocol – The conversation state object
    state
    ConversationStateProtocol
    required
    None
abstractmethod on_event() -> None source Handle a conversation event. This method is called for each event in the conversation and should implement the visualization logic. Parameters:
  • event Event – The event to visualize
    event
    Event
    required
    None
create_sub_visualizer() -> ConversationVisualizerBase | None source Create a visualizer for a sub-agent during delegation. Override this method to support sub-agent visualization in multi-agent delegation scenarios. The sub-visualizer will be used to display events from the spawned sub-agent. By default, returns None which means sub-agents will not have visualization. Subclasses that support delegation (like DelegationVisualizer) should override this method to create appropriate sub-visualizers. Parameters:
  • agent_id str – The identifier of the sub-agent being spawned
Returns:
  • ConversationVisualizerBase | None A visualizer instance for the sub-agent, or None if sub-agent
  • ConversationVisualizerBase | None visualization is not supported
    agent_id
    str
    required
    None

class DefaultConversationVisualizer

Bases: ConversationVisualizerBase Handles visualization of conversation events with Rich formatting. Provides Rich-formatted output with semantic dividers and complete content display.

Methods

init() source Initialize the visualizer. Parameters:
  • highlight_regex dict[str, str] | None – Dictionary mapping regex patterns to Rich color styles for highlighting keywords in the visualizer. For example: {“Reasoning:”: “bold blue”, “Thought:”: “bold green”}
  • skip_user_messages bool – If True, skip displaying user messages. Useful for scenarios where user input is not relevant to show.
    highlight_regex
    dict[str, str] | None
    None
    skip_user_messages
    bool
    None
on_event() -> None source Main event handler that displays events with Rich formatting.
event
Event
required
None