Skip to main content

Module runtime

Module runtime 

Source
Expand description

Python runtime bridge: command dispatch over a dedicated thread. Python runtime manager: owns a dedicated Python thread with an asyncio event loop.

The PythonRuntime struct bridges Rust’s tokio async world with Python’s asyncio by running a command dispatch loop in a dedicated thread. Rust sends PyCommand messages via an mpsc channel, and receives results via per-command oneshot channels.

§Threading architecture

  • One Python thread: All GIL acquisition is confined to a single dedicated thread (agy-bridge-python-runtime). This thread runs an asyncio event loop via pyo3_async_runtimes::tokio::run_until_complete.

  • Concurrent command processing: Commands received from the mpsc channel are not serialized. Each command spawns a future into a FuturesUnordered task set, and tokio::select! drives both incoming commands and in-flight task completions. Multiple chats/operations run concurrently through the Python asyncio event loop.

  • Rust tool dispatch: When the Python SDK invokes a Rust tool, dispatch_rust_tool reads tool state from BRIDGE_STATE, then uses future_into_py to run the async tool on the tokio runtime — keeping the Python thread unblocked for other coroutines.

  • Hook/policy dispatch: Similarly, dispatch_rust_hook and dispatch_rust_policy_confirm use spawn_blocking to run synchronous hook callbacks without holding the GIL.

§Why global state (BRIDGE_STATE)?

The Python SDK’s tool/hook/policy callbacks are dispatched via PyO3 #[pyfunction] entries (e.g. dispatch_rust_tool, dispatch_rust_hook). These functions are registered as plain Python callables and receive only the arguments the SDK passes (agent ID + serialized context). There is no way to thread a Rust reference or Arc through the Python call boundary.

Therefore per-agent state (tool registries, hook runners, policy sets) is stored in a global RwLock<HashMap<AgentId, AgentBridgeState>>. The agent ID is used as a lookup key, and the lock is held only for brief HashMap operations (never across .await points). This is the standard pattern for PyO3 FFI bridges that need to associate Rust state with Python-side identifiers.

Structs§

PythonRuntime
Manages a dedicated Python thread with an asyncio event loop.
RuntimeConfig
Configuration for the bridge runtime.

Constants§

DEFAULT_CHAT_TIMEOUT_SECS
Default timeout (seconds) for a single agent.chat() round-trip. 120s (2 min) is generous for a normal turn while detecting stalls quickly.
DEFAULT_INTER_AGENT_DELAY
Default delay between successive chat commands to prevent burst requests.

Functions§

default_chat_timeout
Returns the default chat round-trip timeout, configurable via AGI_CHAT_TIMEOUT_SECS (defaults to 120 s).
default_operation_timeout
Safety-net timeout for a single send_command round-trip.