Comprehensive Guide for EnvΒΆ
Core ConceptsΒΆ
Three Main Components:ΒΆ
Open World Agents (OWA)'s Env consists of three primary components that enable interaction with the environment in different ways.
-
Callable - Functions you actively call to perform actions or get state
- These are like traditional function calls; you invoke them when you need to perform an action or retrieve some information from the environment.
- Implements
__call__
function - Example:
CALLABLES["std/time_ns"]()
-
Listener - Components that respond to events and execute your callbacks
- Listeners wait for specific events and execute your callback functions when those events occur.
- Takes a
callback
parameter in theconfigure
method - Example:
This example sets up a keyboard listener that invokes
listener = LISTENERS["keyboard"]().configure(callback=my_callback) with listener.session: input("Type enter to exit.")
my_callback
whenever a keyboard event is detected.
-
Runnable - Background processes that can be started and stopped
- Runnables run in the background and can be managed with start and stop operations.
- Parent class of
Listener
, the only difference is absence ofcallback
argument inconfigure
. - Supports
start()
,stop()
, andjoin()
operations
What's the difference between Callable and Listener?
The key difference between these two is who initiates the call:
- In Callable, caller actively executes the Callable.
- In Listener, callee waits for events and then calls user-provided "callbacks".
In other words, Callables are synchronous functions you call directly, while Listeners are asynchronous and react to events.
Common environmental interfaces such as gymnasium.Env only provides object/method equivalent to Callable.
Registry SystemΒΆ
The OWA environment uses a registry system to manage and access the various components.
Components are managed through global registries:
-
CALLABLES
- Dictionary of callable functions -
LISTENERS
- Dictionary of event listeners -
RUNNABLES
- Dictionary of background processes
Zero-Configuration Plugin Discovery: Plugins are automatically discovered when installed via pip using Python's Entry Points system. No manual activation needed!
from owa.core.registry import CALLABLES, LISTENERS, RUNNABLES
# Components automatically available after plugin installation
All components use unified namespace/name
naming pattern for consistency.
Environment Usage ExamplesΒΆ
Standard Environment (owa.env.std
)ΒΆ
Here is an example of how to use the standard environment to interact with clock functionalities.
import time
from owa.core.registry import CALLABLES, LISTENERS
# Components automatically available - no activation needed!
# Unified namespace/name pattern: std/time_ns, std/tick
# Testing the std/tick listener
tick = LISTENERS["std/tick"]().configure(callback=lambda: print(CALLABLES["std/time_ns"]()), interval=1)
tick.start()
time.sleep(2) # The listener prints the current time in nanoseconds a few times
tick.stop(), tick.join()
namespace/name
pattern.
Instead of manual start-stop-join
procedure, you may utilize context manager: .session
! Following example shows how to abbreviate start-stop-join
steps.
Desktop Environment (owa.env.desktop
)ΒΆ
The desktop environment module provides capabilities for UI interaction and input handling.
from owa.core.registry import CALLABLES, LISTENERS
from owa.msgs.desktop.keyboard import KeyboardEvent
# Components automatically available - unified namespace/name pattern
# Using screen capture and window management features
print(f"{CALLABLES['desktop/screen.capture']().shape=}") # Example output: (1080, 1920, 3)
print(f"{CALLABLES['desktop/window.get_active_window']()=}")
print(f"{CALLABLES['desktop/window.get_window_by_title']('open-world-agents')=}")
# Simulating a mouse click (left button, double click)
mouse_click = CALLABLES["desktop/mouse.click"]
mouse_click("left", 2)
# Configuring a keyboard listener
def on_keyboard_event(keyboard_event: KeyboardEvent):
print(f"Keyboard event: {keyboard_event.event_type=}, {keyboard_event.vk=}")
keyboard_listener = LISTENERS["desktop/keyboard"]().configure(callback=on_keyboard_event)
with keyboard_listener.session:
input("Type enter to exit.\n")
Custom EnvPlugin ExampleΒΆ
You can create your own plugins using Entry Points for automatic discovery. For more information, see Custom EnvPlugin.
Creating custom plugins allows you to extend the OWA environment with your own functionalities.
# In your plugin's pyproject.toml:
# [project.entry-points."owa.env.plugins"]
# myplugin = "owa.env.myplugin:plugin_spec"
# In your plugin specification:
from owa.core.plugin_spec import PluginSpec
plugin_spec = PluginSpec(
namespace="myplugin",
version="0.1.0",
description="My custom plugin",
components={
"callables": {
"add": "owa.env.myplugin:add_function",
},
"listeners": {
"events": "owa.env.myplugin:EventListener",
}
}
)
# Using the custom plugin (automatically available after pip install)
from owa.core.registry import CALLABLES, LISTENERS
result = CALLABLES["myplugin/add"](5, 3) # Returns 8
namespace/name
pattern for all components.
Architecture SummaryΒΆ
The diagram below summarizes the architecture of the OWA environment and how components are registered and used.
graph LR;
EP[Entry Points] -->|Auto-discovers| SM["Standard Plugin(owa.env.std)"]
EP -->|Auto-discovers| DM["Desktop Plugin(owa.env.desktop)"]
EP -->|Auto-discovers| MP["Message Package(owa-msgs)"]
SM -->|Provides| C1[std/time_ns]
SM -->|Provides| L1[std/tick Listener]
DM -->|Provides| C2[desktop/screen.capture]
DM -->|Provides| C3[desktop/window.get_active_window]
DM -->|Provides| L2[desktop/keyboard Listener]
MP -->|Provides| M1[desktop/KeyboardEvent]
MP -->|Provides| M2[desktop/MouseEvent]
MP -->|Provides| M3[desktop/ScreenCaptured]
User -->|pip install| PI[Plugin Installation]
PI --> EP
EP --> R[Component Registry]
EP --> MR[Message Registry]
CLI Tools for Plugin ManagementΒΆ
The owl env
command provides powerful tools for managing and exploring plugins with enhanced filtering, search, and analysis capabilities:
Plugin Discovery and ListingΒΆ
# List all discovered plugins
$ owl env list
# Enhanced filtering and display options
$ owl env list --namespace example # Filter by namespace
$ owl env list --type callables # Filter by component type
$ owl env list --search mouse # Search by pattern
$ owl env list --details # Show import paths and load status
$ owl env list --table # Display in table format
$ owl env list --sort name # Sort by name, namespace, or type
Plugin Information and InspectionΒΆ
# Show plugin summary
$ owl env show example
# Enhanced plugin exploration
$ owl env show example --components # Show detailed component list
$ owl env show example --inspect mouse.click # Inspect specific component
$ owl env show example --type callables # Filter by component type
$ owl env show example --search window # Search within namespace
$ owl env show example --table # Display in table format
Advanced Search and DiscoveryΒΆ
# Search across all plugins
$ owl env search "mouse.*click" # Regex pattern search
$ owl env search window --details --table # Detailed search results
$ owl env search keyboard --type callables # Search specific component type
# Quick access shortcuts
$ owl env ls # Quick plugin list
$ owl env ls desktop # Quick namespace exploration
$ owl env find mouse # Quick component search
$ owl env namespaces # List all available namespaces
Ecosystem AnalysisΒΆ
# Statistics and health monitoring
$ owl env stats # Show ecosystem statistics
$ owl env stats --by-namespace # Group by namespace
$ owl env stats --by-type # Group by component type
$ owl env health # Perform health check
Plugin DevelopmentΒΆ
# Validate plugin specifications
$ owl env validate owa.env.myplugin:plugin_spec # Python entry point
$ owl env validate ./plugin.yaml # YAML file
$ owl env validate ./plugin.yaml --verbose # Detailed validation
$ owl env validate ./plugin.yaml --no-check-imports # Skip import validation
Example CLI OutputΒΆ
$ owl env list
π¦ Discovered Plugins (4)
βββ desktop (25 components)
β βββ π Callables: 20
β βββ π Listeners: 5
βββ example (7 components)
β βββ π Callables: 3
β βββ π Listeners: 2
β βββ π Runnables: 2
βββ gst (4 components)
β βββ π Listeners: 2
β βββ π Runnables: 2
βββ std (2 components)
βββ π Callables: 1
βββ π Listeners: 1
$ owl env show example --components
π¦ Plugin: example (7 components)
βββ π Callables: 3
βββ π Listeners: 2
βββ π Runnables: 2
π Callables (3)
βββ example/add
βββ example/callable
βββ example/print
π Listeners (2)
βββ example/listener
βββ example/timer
π Runnables (2)
βββ example/counter
βββ example/runnable
$ owl env search "mouse" --table
Search Results for 'mouse' (9 matches)
βββββββββββββββββββββββββββ³ββββββββββββ³ββββββββββββ³ββββββββββββββββββ
β Component β Type β Namespace β Name β
β‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©
β desktop/mouse β listeners β desktop β mouse β
β desktop/mouse.click β callables β desktop β mouse.click β
β desktop/mouse.move β callables β desktop β mouse.move β
β desktop/mouse.press β callables β desktop β mouse.press β
β desktop/mouse.scroll β callables β desktop β mouse.scroll β
βββββββββββββββββββββββββββ΄ββββββββββββ΄ββββββββββββ΄ββββββββββββββββββ
$ owl env namespaces
Available Namespaces
βββββββββββββ³βββββββββββββ³βββββββββββββββββββββ
β Namespace β Components β Quick Access β
β‘ββββββββββββββββββββββββββββββββββββββββββββββ©
β desktop β 25 β owl env ls desktop β
β example β 7 β owl env ls example β
β gst β 4 β owl env ls gst β
β std β 2 β owl env ls std β
βββββββββββββ΄βββββββββββββ΄βββββββββββββββββββββ
Message RegistryΒΆ
OWA provides a centralized message registry system that automatically discovers and manages message definitions through Python entry points. This system separates message schemas from runtime components, providing better organization and extensibility.
Accessing MessagesΒΆ
from owa.core import MESSAGES
# Access message classes by type name
KeyboardEvent = MESSAGES['desktop/KeyboardEvent']
MouseEvent = MESSAGES['desktop/MouseEvent']
ScreenCaptured = MESSAGES['desktop/ScreenCaptured']
# Check if a message type exists
if 'desktop/KeyboardEvent' in MESSAGES:
print("KeyboardEvent is available")
# List all available message types
for message_type in MESSAGES.keys():
print(f"Available: {message_type}")
# Create message instances
event = KeyboardEvent(event_type="press", vk=65, timestamp=1234567890)
Message Naming ConventionΒΆ
Messages follow a domain-based naming pattern:
- Format: domain/MessageType
- Domain: Logical grouping (e.g., desktop
, sensors
, system
)
- MessageType: PascalCase message name
- Examples: desktop/KeyboardEvent
, desktop/WindowInfo
, sensors/TemperatureReading
Core Message TypesΒΆ
The owa-msgs
package provides standard message definitions:
Message Type | Description |
---|---|
desktop/KeyboardEvent |
Keyboard press/release events |
desktop/KeyboardState |
Current keyboard state |
desktop/MouseEvent |
Mouse movement, clicks, scrolls |
desktop/MouseState |
Current mouse position and buttons |
desktop/ScreenCaptured |
Screen capture frames with timestamps |
desktop/WindowInfo |
Active window information |
CLI Tools for Message ManagementΒΆ
# List all available message types
$ owl messages list
# Show detailed message schema
$ owl messages show desktop/KeyboardEvent
# Search for specific message types
$ owl messages search keyboard
# Validate message definitions
$ owl messages validate
Custom Message RegistrationΒΆ
Third-party packages can register custom message types through entry points:
# pyproject.toml
[project.entry-points."owa.msgs"]
"sensors/TemperatureReading" = "custom_sensors.messages:TemperatureReading"
"sensors/HumidityReading" = "custom_sensors.messages:HumidityReading"
Additional ResourcesΒΆ
- For standard module details: owa-env-std
- For desktop features: owa-env-desktop
- For multimedia support: owa-env-gst
- For custom EnvPlugin development: custom_plugins.md