BaseEvent is the typed payload + runtime state object that flows through the bus.
Use subclassing (Python) or BaseEvent.extend(...) (TypeScript) to define event payload fields.
Defining events
- Python
- TypeScript
- Go
- Rust
- Immediate path:
await event.now()(Python/TypeScript),event.Now()(Go),event.now().await(Rust) - Queue-order path:
await event.wait()(Python/TypeScript),event.Wait()(Go),event.wait().await(Rust)
now() and wait() accept the wait-shaping options (first_result and timeout). Result filtering and error policy live on event_result() / event_results_list().
Python also supports await event as a Python-only shortcut for await event.now(). Other runtimes require the explicit now() / wait() methods.
In Go the same split is exposed as event.Now() for immediate queue-jump execution and event.Wait() for normal queue-order waiting.
In Rust the same split is exposed as event.now().await for immediate queue-jump execution and event.wait().await for normal queue-order waiting.
Unset event option fields are not hydrated onto the event at emit time; the bus that actually processes the event resolves its defaults at execution time.
Core metadata fields
Common event metadata fields available in all runtimes:event_id: unique UUIDv7event_type: event name/type keyevent_version: payload version markerevent_result_type: expected handler return schema/typeevent_timeout: per-event timeout override (None/nullmeans use the current processing bus default at execution time;0disables)event_handler_timeout: per-handler timeout cap overrideevent_handler_slow_timeout: per-handler slow warning threshold (None/nullmeans use the current processing bus default;0disables)event_slow_timeout: per-event slow warning threshold (None/nullmeans use the current processing bus default;0disables)event_concurrency: event scheduling mode override (None/null/zero-value mode means use the current processing bus default)event_handler_concurrency: handler scheduling mode override (None/null/zero-value mode means use the current processing bus default)event_handler_completion: handler completion strategy override (None/null/zero-value mode means use the current processing bus default)
Runtime fields
event_status: pending/started/completedevent_created_at,event_started_at,event_completed_atevent_started_at/event_completed_atareNone(Python) /null(TypeScript) until setevent_parent_idandevent_emitted_by_handler_idareNone/nullwhen unsetevent_blocks_parent_completion:True/trueonly for linked children awaited from the handler that emitted themevent_path: buses traversedevent_results: per-handler result entries- Child-event tracking (
event_children/descendants)
Completion model
Events are returned in pending state fromemit(), then complete asynchronously.
- Python
- TypeScript
- Go
- Rust
Result access helpers
Result helpers share the same defaults in all runtimes:raise_if_any=true: raise when any handler result is an error.raise_if_none=false: returnNone/undefined/nil/[]when no result matches the filter.- If every handler errors, only
raise_if_any=falseplusraise_if_none=falsesuppresses the error. Any other combination raises. - A single handler error is raised as that error; multiple handler errors are raised as an aggregate/exception-group shape.
First Result
- Python
- TypeScript
- Go
- Rust
All results
- Python
- TypeScript
- Go
- Rust
Per-handler result entries
You can create/update a specificEventResult entry for a handler (useful for controlled seeding/rehydration flows).
- Python
- TypeScript
- Go
- Rust
Resetting an event
You can create a fresh pending copy for re-emit.- Python
- TypeScript
- Go
- Rust
Serialization
Events are JSON-serializable in all runtimes for bridge and cross-runtime workflows.- Python
- TypeScript
- Go
- Rust
Notes
- Reserved names are validated in all runtimes:
- runtime API names such as
bus,emit,now, andwaitcannot be provided as payload fields where they would collide with event methods/properties. - Unknown
event_*fields are rejected. - Known built-in
event_*fields (for exampleevent_timeout) can still be intentionally overridden in event definitions.
- runtime API names such as
model_*is also reserved:- Python: unknown
model_*fields are rejected, but valid Pydantic namespace overrides (for examplemodel_config) are allowed. - TypeScript: any
model_*field is rejected.
- Python: unknown
event_result_typedrives handler return validation in all runtimes.- Parent-child tracking is automatic for
event.emit(...)inside handlers.bus.emit(...)creates a top-level event with no parent link.
Reserved Fields
- Python
- TypeScript
- Go
- Rust