Skip to main content

Event Triggers

Event triggers allow BindAI automation logic to react when an event is published through an EventBus. The current implementation provides a lightweight EventTrigger abstraction. An EventTrigger subscribes to one named event and calls a target function whenever that event is published. This makes event-driven automation possible without coupling the trigger to a specific agent, workflow, or application object. For background execution, an event-trigger target can invoke an AutomationWorker. Event triggering and background execution remain separate responsibilities.

EventTrigger

The implementation is located at:
EventTrigger extends the base Trigger class and requires three values:
  • an EventBus
  • an event name
  • a callable target
Conceptually:
The target receives the published Event object.
The trigger does not create or own the event bus. It subscribes to an existing bus supplied by the application.

Trigger Lifecycle

Every trigger inherits from the base Trigger abstraction. The base class provides:
It also defines:
EventTrigger implements these lifecycle operations by subscribing and unsubscribing from its configured EventBus.

Attaching

Calling:
subscribes the trigger to its configured event. After attachment, matching events are delivered to the trigger. Calling attach() more than once does not create duplicate subscriptions. The implementation tracks whether the trigger is already attached.

Detaching

Calling:
removes the trigger’s subscription from the event bus. Calling detach() when the trigger is already detached is safe.

Enabling and Disabling

Triggers are enabled by default. A trigger can be temporarily disabled:
When disabled, the trigger ignores published events. It can later be enabled again:
The trigger remains attached to the event bus while disabled; it simply does not invoke its target. This allows applications to pause an attached trigger without rebuilding its subscription.

Event Bus

EventTrigger does not create its own event system. Instead, it receives an existing EventBus:
The event bus is responsible for publishing events and dispatching them to subscribed handlers. This keeps event triggers independent from the source of the events. For example, an event bus can belong to an ExecutionContext:
The trigger only depends on the EventBus interface. It does not need to know which component created the event bus.

Event Names

EventTrigger subscribes to the event name supplied when it is created:
The trigger subscribes through the event bus:
Therefore, the trigger follows the event naming and dispatch behavior of the configured EventBus. Use event names that correspond to events actually published by the application. BindAI currently publishes structured events for areas including:
  • application lifecycle
  • agent execution
  • workflow execution
  • workflow nodes
  • human tasks
  • model requests and responses
  • tool execution
  • memory operations
  • MCP connection lifecycle
The exact event names should be based on the events published by the connected BindAI components.

Event Objects

The target receives the complete Event instance:
This allows the target to inspect the event’s structured information rather than receiving only a raw payload. The exact payload fields depend on the specific event being published.

Example with an Execution Context

A simple event-driven setup can use the event bus owned by an ExecutionContext:
When a matching event is published through context.events, the trigger calls handle_agent_event. When the trigger is no longer required:

Trigger Targets

The target must be a callable that accepts an Event:
Callable objects can also be used:
The current EventTrigger implementation does not impose a special target interface beyond the callable receiving an Event.

Multiple Triggers

Multiple triggers can subscribe to the same event bus. For example:
Each trigger listens for its configured event name. This allows different automation actions to react to different events while sharing the same event source.

Multiple Triggers for One Event

Multiple triggers can also subscribe to the same event:
Both targets can receive the matching event according to the configured EventBus dispatch behavior.

Trigger Lifecycle and Application Lifecycle

Triggers should normally be attached during application or automation initialization and detached when they are no longer required. A typical lifecycle is:
The trigger itself does not provide application lifecycle management. The application is responsible for deciding when triggers should be created, attached, disabled, enabled, and detached.

EventTrigger and Automation

An EventTrigger is a trigger mechanism. It does not itself define an automation workflow or persist automation state. Its responsibility is intentionally small:
If the target starts a larger automation process, that behavior belongs to the target or to the automation components it invokes. This separation keeps event subscription independent from automation execution.

EventTrigger and AutomationWorker

EventTrigger and AutomationWorker solve different problems. EventTrigger determines when application logic should run:
AutomationWorker determines how an automation definition is executed:
An application can combine them when an event should start a background automation. For example:
The conceptual flow is:
The important distinction is that EventTrigger itself does not create a background worker. If the target calls AutomationWorker.submit(), the application explicitly chooses background execution.

AutomationWorker Execution Model

In BindAI v0.1, AutomationWorker provides both synchronous and background execution. Synchronous execution:
Background execution:
The background worker uses an in-process ThreadPoolExecutor. Conceptually:
The worker is therefore process-local. It is not a separate worker service and does not provide distributed queue coordination.

Background Event Handling

An event trigger can explicitly delegate work to an AutomationWorker:
This produces:
This pattern is useful when the event handler should hand work to the in-process background executor rather than perform the entire automation directly inside the event handler. The worker lifecycle remains the responsibility of the application:
It can also be used as a context manager:

EventTrigger and Workflows

An event trigger can be used as the entry point for application logic that invokes a workflow. For example:
The exact workflow invocation depends on how the application has configured its workflow and execution context. EventTrigger itself does not contain workflow-specific logic. The same principle applies when a trigger invokes another BindAI executable.

EventTrigger and Agents

An event trigger can listen to an event bus associated with an execution context used by agent execution. For example:
The important abstraction is the EventBus, not a hard-coded agent.events attribute. Applications should pass the event bus that actually publishes the events they want to observe.

EventTrigger and Connections

An event trigger can also invoke application logic that uses a BindAI Connection. For example:
The automation package does not directly manage Connections. Connection configuration and lifecycle remain the responsibility of the application or integration layer.

Wildcard Events

The underlying EventBus supports wildcard subscriptions through the "*" event name. For example:
This is an EventBus capability rather than special behavior implemented by EventTrigger. EventTrigger subscribes using the event name supplied to its constructor:
Therefore, wildcard behavior should be understood as part of the configured EventBus semantics.

Handler Execution

When a matching event is received, EventTrigger checks whether it is enabled:
If the trigger is enabled, it invokes its target:
The current implementation does not add a separate retry, queue, persistence, or scheduling layer around the target call. Those concerns belong to the surrounding application or automation architecture.

Synchronous Event Dispatch

The underlying BindAI EventBus dispatches subscribed handlers synchronously. Conceptually:
EventTrigger itself does not create a background thread or process. If the target calls AutomationWorker.submit(), background execution begins explicitly through the worker. This distinction is important:
The trigger should not be treated as a distributed job queue.

Trigger Registry

Trigger registration and lookup are separate from the EventTrigger implementation. EventTrigger itself does not maintain a global registry. If an application uses TriggerRegistry, the registry is responsible for managing trigger instances while EventTrigger remains responsible for subscribing to and unsubscribing from its event source. For example:
Registering a trigger does not automatically attach it to its event source. Attachment remains explicit:

Error Handling

EventTrigger does not wrap the target callable in its own retry or error-management mechanism. The target is invoked directly:
The underlying EventBus isolates exceptions raised by event handlers and logs the failure rather than allowing one handler failure to prevent other subscribed handlers from being processed. Applications should still handle expected failures at the appropriate application or automation layer. For example:
Do not assume that EventTrigger automatically retries failed targets.

Security Considerations

Event payloads may contain application data. Targets should therefore treat incoming events as application input and validate or sanitize values when necessary. Recommended practices include:
  • validate event payloads before performing sensitive actions
  • avoid exposing secrets through event payloads
  • avoid logging credentials or tokens
  • restrict which components can publish sensitive events
  • keep event targets narrowly scoped
  • use appropriate authorization before performing external actions
An event trigger should not be treated as an authorization boundary by itself. When an event starts an automation that performs external side effects, the target or automation should apply the appropriate authorization and validation controls.

Testing Event Triggers

Event triggers can be tested using an isolated EventBus. Example:
Tests should verify at least:
  • the trigger attaches correctly
  • matching events invoke the target
  • disabled triggers do not invoke the target
  • detached triggers no longer receive events
  • repeated attach() does not duplicate subscriptions
  • repeated detach() is safe
  • multiple triggers can receive the same event according to EventBus behavior
When testing a trigger that starts background automation, the worker can be tested separately from the event subscription itself.

Current Implementation

The current event-trigger implementation provides:
  • Trigger base abstraction
  • trigger enable/disable state
  • attach() lifecycle
  • detach() lifecycle
  • EventTrigger
  • explicit EventBus dependency
  • event-name subscription through EventBus.subscribe()
  • callable event targets
  • delivery of the original Event object
  • duplicate-attachment protection
  • safe repeated detachment
The related automation package also provides AutomationWorker for explicit synchronous or in-process background execution. The trigger and worker remain separate abstractions.

Current Limitations

The current EventTrigger implementation does not provide:
  • persistent trigger state
  • durable event delivery
  • distributed event processing
  • trigger-specific queues
  • automatic retries
  • dead-letter handling
  • built-in scheduling
  • built-in authentication
  • built-in authorization
  • distributed worker coordination
The current AutomationWorker also does not provide:
  • distributed job queues
  • cross-process worker coordination
  • automatic failover
  • worker autoscaling
  • durable distributed execution
These capabilities require additional infrastructure outside the current trigger abstraction.

Architecture

The current relationship can be summarized as:
This separation makes it possible to connect existing BindAI event sources to application-specific automation behavior without embedding automation execution into the event bus.

Relationship to Observability

BindAI also provides structured events for runtime observability. An EventRecorder can subscribe to an EventBus and retain events in memory for inspection. This is separate from EventTrigger:
A recorder observes events, while an EventTrigger reacts to a configured event by invoking a target. The same EventBus can therefore have multiple independent subscribers.

Current Scope

For BindAI v0.1, event triggers provide a simple foundation for event-driven automation. The recommended architecture is:
This is sufficient for lightweight in-process event-driven behavior. Background execution remains explicit through AutomationWorker.

Future Direction

Future versions can build on this foundation to provide more advanced event-driven execution, including:
  • durable event processing
  • queue-backed automation
  • distributed workers
  • retry policies
  • dead-letter handling
  • persistent trigger state
  • richer event routing
  • external event sources
  • distributed scheduling
  • production tracing and metrics
These capabilities are not part of the current EventTrigger implementation and should not be assumed to be available in BindAI v0.1.

Summary

EventTrigger connects an existing EventBus to a callable target. The basic lifecycle is:
The trigger can be enabled or disabled without recreating the subscription:
When an event should start background automation, the target can explicitly submit an automation to AutomationWorker:
The responsibilities remain separate:
The current implementation intentionally focuses on one responsibility: When a configured event is published, invoke the configured target if the trigger is enabled. AutomationWorker provides the separate in-process execution capability when the application needs background automation. More advanced durable and distributed automation capabilities remain separate roadmap work.