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 viapyo3_async_runtimes::tokio::run_until_complete. -
Concurrent command processing: Commands received from the
mpscchannel are not serialized. Each command spawns a future into aFuturesUnorderedtask set, andtokio::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_toolreads tool state fromBRIDGE_STATE, then usesfuture_into_pyto run the async tool on the tokio runtime — keeping the Python thread unblocked for other coroutines. -
Hook/policy dispatch: Similarly,
dispatch_rust_hookanddispatch_rust_policy_confirmusespawn_blockingto 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§
- Python
Runtime - Manages a dedicated Python thread with an asyncio event loop.
- Runtime
Config - 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_commandround-trip.