Attach to an agent's plugins: list with a per-agent config map.
use Jido.Agent,
name: "my_robot",
plugins: [{BB.Jido.Plugin.Robot, %{robot: MyRobot}}]
Config
Config is validated against the plugin's config_schema when the agent
is defined — a missing :robot, a mistyped value, or an unrecognised
key (e.g. a typo'd gated_action:) raises at compile time rather than
surfacing later at runtime.
| Key | Type | Required | Default | Description |
|---|
:robot | module() | yes | — | The Beam Bots robot module |
:topics | [[atom()]] | no | [[:state_machine]] | PubSub paths the bridge subscribes to |
:message_types | [module()] | no | [] | Payload modules to filter on ([] = no filter) |
:throttle_ms | pos_integer() | no | nil | Minimum interval between same-type signals |
:gated_actions | [module()] | no | [] | Actions refused before execution unless BB.Safety.state/1 is :armed |
With gated_actions: [BB.Jido.Action.Command, BB.Jido.Action.Reactor],
routed signals resolving to those actions fail closed with
{:error, {:safety_not_armed, state}} via the plugin's
prepare_action/3 hook. The gate authorises the configured robot, so
a gated action whose params name a different robot is rejected with
{:error, {:robot_mismatch, %{configured: ..., requested: ..., action: ...}}}
rather than authorised against the wrong robot's safety state. The gate
covers signal-routed execution only — direct run/2 calls bypass it, so
keep BB.Jido.Action.SafetyAware on actions that must be guarded
everywhere.
State
The plugin owns the agent's :robot state slice:
| Field | Type | Initial | Description |
|---|
:robot | module() | the configured robot | Mirror of config[:robot] for convenience |
:safety_state | atom() | :unknown | Cached safety state (:armed, :disarmed, :disarming, or :error); updated by the routed BB.Jido.Action.UpdateSafetyState when a bb.state.transition signal carries a safety transition |
:last_safety_error | BB.Safety.HardwareError.t() | nil | nil | Last hardware error; updated by the routed BB.Jido.Action.RecordSafetyError when the [:safety, :error] topic is bridged |
:last_joint_state | map() | %{} | Last read %{positions: ..., velocities: ...}; updated whenever BB.Jido.Action.GetJointState runs |
Built-in actions
Child processes
The plugin's child_spec/1 returns one supervised child:
| Child | Type | :id | Restart |
|---|
BB.Jido.PubSubBridge | :worker | {BB.Jido.Plugin.Robot, :pub_sub_bridge, robot} | :transient |
The bridge is mounted by the plugin, but you can also start it directly
under a different supervisor if you want PubSub-to-Signal forwarding
without an agent.
{:ok, bridge} =
BB.Jido.PubSubBridge.start_link(
robot: MyRobot,
agent: agent_pid_or_name,
topics: [[:state_machine]]
)
| Option | Type | Required | Default | Description |
|---|
:robot | module() | yes | — | Robot module to subscribe against |
:agent | GenServer.server() | yes | — | Where to cast signals (pid, registered name, via-tuple) |
:topics | [[atom()]] | no | [[:state_machine]] | PubSub paths |
:message_types | [module()] | no | [] | Payload filter |
:throttle_ms | pos_integer() | no | nil | Same-type throttle in ms |
:name | GenServer.name() | no | — | Standard GenServer.start_link option |
All standard GenServer.start_link options (:timeout, :debug,
:spawn_opt, :hibernate_after) are also accepted.
Action schemas
Each action's :schema is documented below using [type:, required:, default:]
notation matching the NimbleOptions format that Jido.Action accepts.
| Param | Type | Required | Default |
|---|
:robot | :atom | ✓ | — |
:command | :atom | ✓ | — |
:goal | :map | | %{} |
:timeout | :pos_integer | | 30_000 |
| Param | Type | Required | Default |
|---|
:robot | :atom | ✓ | — |
:reactor | :atom | ✓ | — |
:inputs | :map | | %{} |
| Param | Type | Required | Default |
|---|
:robot | :atom | ✓ | — |
:target | :atom | ✓ | — |
:timeout | :pos_integer | | 30_000 |
| Param | Type | Required | Default |
|---|
:robot | :atom | ✓ | — |