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: ConversationIDstate: ConversationStateProtocolconversation_stats: ConversationStatsconfirmation_policy_active: boolis_confirmation_mode_active: bool Check if confirmation mode is active.
- The conversation state has a security analyzer set (not None)
- 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:-
messagestr | Message – Either a string (which will be converted to a user message) or a Message object -
senderstr | 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.NoneNone
None
None
None
None
llmLLM | None – Optional LLM to use for title generation. If not provided, uses the agent’s LLM.max_lengthint – Maximum length of the generated title.
- str A generated title for the conversation.
-
ValueError– If no user messages are found in the conversation.NoneNone
persistence_base_dirstr | Path – Base directory for persistence. Can be a string path or Path object.conversation_idConversationID – Unique conversation ID.
- str String path to the conversation-specific persistence directory.
-
str Always returns a normalized string path even if a Path was provided.
NoneNone
conversation.run() is
executing in another thread.
Parameters:
questionstr – A simple string question to ask the agent
-
str A string response from the agent
None
ValueError– If no condenser is configured or the condenser doesn’t handle condensation requests.
- Pre-run setup operations (e.g., indexing repositories)
- Manual tool execution for environment setup
- Testing tool behavior outside the agent loop
tool_namestr – The name of the tool to execute (e.g., “sleeptime_compute”)actionAction – The action to pass to the tool executor
- Observation The observation returned by the tool execution
-
KeyError– If the tool is not found in the agent’s tools -
NotImplementedError– If the tool has no executorNoneNone
callbacksIterable[CallbackType] – An iterable of callback functions
-
CallbackType A single callback function that calls all provided callbacks
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 sourceNone
None
None
None
-
TimeoutError– If the lock cannot be acquired within LOCK_TIMEOUT_SECONDS. -
ValueError– If an event with the same ID already exists.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.None
class WebSocketConnectionError
Bases:RuntimeError
Raised when WebSocket connection fails to establish within the timeout.
Properties
conversation_idtimeout
Methods
init() -> None sourceNone
None
None
class LocalConversation
Bases:BaseConversation
Properties
agent: AgentBaseworkspace: LocalWorkspacemax_iteration_per_run: intllm_registry: LLMRegistrydelete_on_close: boolid: ConversationID Get the unique ID of the conversation.state: ConversationState Get the conversation state.
conversation_statsstuck_detector: StuckDetector | None Get the stuck detector instance if enabled.resolved_plugins: list[ResolvedPluginSource] | None Get the resolved plugin sources after plugins are loaded.
Methods
init() source Initialize the conversation. Parameters:-
agentAgentBase – The agent to use for the conversation. -
workspacestr | Path | LocalWorkspace – Working directory for agent operations and tool execution. Can be a string path, Path object, or LocalWorkspace instance. -
pluginslist[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_dirstr | Path | None – Directory for persisting conversation state and events. Can be a string path or Path object. -
conversation_idConversationID | 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. -
callbackslist[ConversationCallbackType] | None – Optional list of callback functions to handle events -
token_callbackslist[ConversationTokenCallbackType] | None – Optional list of callbacks invoked for streaming deltas -
hook_configHookConfig | None – Optional hook configuration to auto-wire session hooks. If plugins are loaded, their hooks are combined with this config. -
max_iteration_per_runint – Maximum number of iterations per run -
visualizertype[ConversationVisualizerBase] | ConversationVisualizerBase | None – Visualization configuration. Can be:- ConversationVisualizerBase subclass: Class to instantiate (default: ConversationVisualizer)
- ConversationVisualizerBase instance: Use custom visualizer
- None: No visualization
-
stuck_detectionbool – Whether to enable stuck detection -
stuck_detection_thresholdsStuckDetectionThresholds | 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. -
cipherCipher | 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.NoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNone
-
messagestr | Message – Either a string (which will be converted to a user message) or a Message object -
senderstr | 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.NoneNone
- First call: creates actions but doesn’t execute them, stops and waits
- Second call: executes pending actions (implicit confirmation)
- Creates and executes actions immediately
None
None
-
secretsMapping[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.None
None
conversation.run() is
executing in another thread.
Parameters:
questionstr – A simple string question to ask the agent
-
str A string response from the agent
None
llmLLM | None – Optional LLM to use for title generation. If not provided, uses self.agent.llm.max_lengthint – Maximum length of the generated title.
- str A generated title for the conversation.
-
ValueError– If no user messages are found in the conversation.NoneNone
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
tool_namestr – The name of the tool to execute (e.g., “sleeptime_compute”)actionAction – The action to pass to the tool executor
- Observation The observation returned by the tool execution
-
KeyError– If the tool is not found in the agent’s tools -
NotImplementedError– If the tool has no executorNoneNone
class RemoteConversation
Bases:BaseConversation
Properties
agent: AgentBasemax_iteration_per_run: intworkspace: RemoteWorkspacedelete_on_close: boolid: ConversationIDstate: RemoteState Access to remote conversation state.conversation_statsstuck_detectorStuck detector for compatibility. Not implemented for remote conversations.
Methods
init() -> None source Remote conversation proxy that talks to an agent server. Parameters:-
agentAgentBase – Agent configuration (will be sent to the server) -
workspaceRemoteWorkspace – The working directory for agent operations and tool execution. -
pluginslist | None – Optional list of plugins to load on the server. Each plugin is a PluginSource specifying source, ref, and repo_path. -
conversation_idConversationID | None – Optional existing conversation id to attach to -
callbackslist[ConversationCallbackType] | None – Optional callbacks to receive events (not yet streamed) -
max_iteration_per_runint – Max iterations configured on server -
stuck_detectionbool – Whether to enable stuck detection on server -
stuck_detection_thresholdsStuckDetectionThresholds | 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_configHookConfig | None – Optional hook configuration for session hooks -
visualizertype[ConversationVisualizerBase] | ConversationVisualizerBase | None – Visualization configuration. Can be:- ConversationVisualizerBase subclass: Class to instantiate (default: ConversationVisualizer)
- ConversationVisualizerBase instance: Use custom visualizer
- None: No visualization
-
secretsMapping[str, SecretValue] | None – Optional secrets to initialize the conversation withNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNoneNone
None
None
blockingbool – If True (default), wait for the run to complete by polling the server. If False, return immediately after triggering the run.poll_intervalfloat – Time in seconds between status polls (only used when blocking=True). Default is 1.0 second.timeoutfloat – Maximum time in seconds to wait for the run to complete (only used when blocking=True). Default is 3600 seconds.
-
ConversationRunError– If the run fails or times out.NoneNoneNone
None
None
None
None
conversation.run() is
executing in another thread.
Parameters:
questionstr – A simple string question to ask the agent
-
str A string response from the agent
None
llmLLM | 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_lengthint – Maximum length of the generated title.
-
str A generated title for the conversation.
NoneNone
HTTPError– If the server returns an error (e.g., no condenser configured).
tool_namestr – The name of the tool to executeactionAction – The action to pass to the tool executor
-
NotImplementedError– Always, as this feature is not yet supported for remote conversations.NoneNone
- By calling the finish tool
- By returning a text message with no tool calls
eventsSequence[Event] – List of conversation events to search through.
-
str The final response message from the agent, or empty string if not found.
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:-
secretsMapping[str, SecretValue] – Dictionary mapping secret keys to either string values or callable functions that return string valuesNone
textstr – The text to search for secret keys
-
set[str] Set of secret keys found in the text
None
commandstr – The bash command to check for secret references
-
dict[str, str] Dictionary of environment variables to export (key -> value)
None
textstr – The text to mask secrets in
-
str Text with secret values replaced by
<secret-hidden>None
class ConversationExecutionStatus
Bases:str, Enum
Enum representing the current execution state of the conversation.
Properties
IDLERUNNINGPAUSEDWAITING_FOR_CONFIRMATIONFINISHEDERRORSTUCKDELETING
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 IDagent: 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: ConversationExecutionStatusconfirmation_policy: ConfirmationPolicyBasesecurity_analyzer: SecurityAnalyzerBase | None Optional security analyzer to evaluate action risks.activated_knowledge_skills: list[str] List of activated knowledge skills nameblocked_actions: dict[str, str] Actions blocked by PreToolUse hooks, keyed by action IDblocked_messages: dict[str, str] Messages blocked by UserPromptSubmit hooks, keyed by message IDstats: ConversationStats Conversation statistics for tracking LLM metricssecret_registry: SecretRegistry Registry for handling secrets and sensitive dataevents: EventLogenv_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:-
callbackConversationCallbackType | None – A function that takes an Event (ConversationStateUpdateEvent) or None to remove the callbackNone
idConversationID – Unique conversation identifieragentAgentBase – The Agent to use (tools must match persisted on restore)workspaceBaseWorkspace – Working directory for agent operationspersistence_dirstr | None – Directory for persisting state and eventsmax_iterationsint – Maximum iterations per runstuck_detectionbool – Whether to enable stuck detectioncipherCipher | 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.
- ConversationState ConversationState ready for use
-
ValueError– If conversation ID or tools mismatch on restore -
ValidationError– If agent or other fields fail Pydantic validationNoneNoneNoneNoneNoneNoneNone
None
None
None
None
None
None
eventsSequence[Event] – List of events to search through
- list[ActionEvent] List of ActionEvent objects that don’t have corresponding observations,
-
list[ActionEvent] in chronological order
None
blockingbool – If True, block until lock is acquired. If False, return immediately.timeoutfloat – Maximum time to wait for lock (ignored if blocking=False). -1 means wait indefinitely.
-
bool True if lock was acquired, False otherwise.
NoneNone
RuntimeError– If the current thread doesn’t own the lock.
class StuckDetector
Detects when an agent is stuck in repetitive or unproductive patterns. This detector analyzes the conversation history to identify various stuck patterns:- Repeating action-observation cycles
- Repeating action-error cycles
- Agent monologue (repeated messages without user input)
- Repeating alternating action-observation patterns
- Context window errors indicating memory issues
Properties
state: ConversationStatethresholds: StuckDetectionThresholdsaction_observation_threshold: intaction_error_threshold: intmonologue_threshold: intalternating_pattern_threshold: int
Methods
init() sourceNone
None
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:
- Create a visualizer instance:
viz = MyVisualizer() - Pass it to Conversation:
conv = Conversation(agent, visualizer=viz) - Conversation automatically calls
viz.initialize(state)to attach the state
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:-
stateConversationStateProtocol – The conversation state objectNone
-
eventEvent – The event to visualizeNone
agent_idstr – The identifier of the sub-agent being spawned
- ConversationVisualizerBase | None A visualizer instance for the sub-agent, or None if sub-agent
-
ConversationVisualizerBase | None visualization is not supported
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_regexdict[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_messagesbool – If True, skip displaying user messages. Useful for scenarios where user input is not relevant to show.NoneNone
None

