Jido v2 plugin that gives an agent the ability to control a Beam Bots robot.
Provides:
- The standard robot-control actions:
BB.Jido.Action.Command,BB.Jido.Action.Reactor,BB.Jido.Action.WaitForState, andBB.Jido.Action.GetJointState. - Default signal routes for the canonical
bb.*signal types, including routes that keep the plugin state current:bb.state.transitionis routed toBB.Jido.Action.UpdateSafetyStateandbb.safety.errortoBB.Jido.Action.RecordSafetyError. - Plugin-owned state under
agent.state.robot: the configured:robotmodule, a cached:safety_state(updated by the routedUpdateSafetyStateaction whenever a safety transition arrives), the:last_safety_error(updated byRecordSafetyErrorwhen the[:safety, :error]topic is bridged), and:last_joint_state(updated wheneverGetJointStateruns). - A supervised
BB.Jido.PubSubBridgemounted under the agent process that forwards BB PubSub events to the agent as Jido signals. - An optional fail-closed safety gate: actions listed in
:gated_actionsare refused before execution unless the robot's safety controller reports:armed.
Configuration
Plugin config (passed via {BB.Jido.Plugin.Robot, %{...}} when attaching
to an agent) is validated against the plugin's config_schema when the
agent is defined, so a missing, mistyped, or unrecognised option fails
fast with a schema error rather than surfacing later at runtime:
:robot— robot module (required).:topics— list ofBB.PubSubpaths to bridge (default[[:state_machine]]; replaces the default rather than adding to it).:message_types— payload modules to filter on at subscribe time (default[], meaning no filter).:throttle_ms— optional per-signal-type throttle in milliseconds.:gated_actions— list of action modules refused viaprepare_action/3unlessBB.Safety.state/1reports:armed(default[]). See below.
Bridged topics beyond the defaults need matching signal routes on the agent (or plugin) — signals without a route are reported as routing errors through the agent's error policy.
Safety gating
With gated_actions: [BB.Jido.Action.Command, BB.Jido.Action.Reactor],
any routed signal that resolves to one of those actions is refused with
{:error, {:safety_not_armed, state}} before the action executes,
using an authoritative BB.Safety.state/1 read (fast ETS). This is the
plugin-level counterpart to the per-action BB.Jido.Action.SafetyAware
mixin: the mixin travels with the action module wherever it's used,
while the gate is enforced centrally for signal-routed execution on this
agent. The gate fails closed and cannot be bypassed by the routed
action's own params: a gated action whose params name a robot other
than the configured one is rejected with
{:error, {:robot_mismatch, details}} rather than authorised against
the wrong robot's safety state.
The gate only sees signal-routed execution — direct run/2 calls (e.g.
reactor steps) bypass it, so keep using SafetyAware for actions that
must be guarded everywhere.
Example
defmodule MyRobot.Agent do
use Jido.Agent,
name: "my_robot",
plugins: [
{BB.Jido.Plugin.Robot,
%{robot: MyRobot, gated_actions: [BB.Jido.Action.Command]}}
]
endThe plugin is a singleton: one robot per agent, and as: aliasing is
rejected at agent definition. To control several robots, run one agent
per robot.
Summary
Functions
Returns metadata for Jido.Discovery integration.
Returns the list of action modules provided by this plugin.
Returns the capabilities provided by this plugin.
Returns the plugin's category.
Returns the Zoi schema for per-agent configuration.
Returns the plugin's description.
Returns the plugin manifest with all metadata.
Returns the plugin's name.
Returns the OTP application for config resolution.
Returns the plugin specification with optional per-agent configuration.
Returns the requirements for this plugin.
Returns the schedules for this plugin.
Returns the Zoi schema for plugin state.
Returns the signal patterns this plugin handles.
Returns the signal routes for this plugin.
Returns whether this plugin is a singleton.
Returns the key used to store plugin state in the agent.
Returns the sensor subscriptions for this plugin.
Returns the plugin's tags.
Returns the plugin's version.
Functions
@spec __plugin_metadata__() :: map()
Returns metadata for Jido.Discovery integration.
This function is used by Jido.Discovery to index plugins
for fast lookup and filtering.
@spec actions() :: [module()]
Returns the list of action modules provided by this plugin.
@spec capabilities() :: [atom()]
Returns the capabilities provided by this plugin.
@spec category() :: String.t() | nil
Returns the plugin's category.
@spec config_schema() :: Zoi.schema() | nil
Returns the Zoi schema for per-agent configuration.
@spec description() :: String.t() | nil
Returns the plugin's description.
@spec manifest() :: Jido.Plugin.Manifest.t()
Returns the plugin manifest with all metadata.
The manifest provides compile-time metadata for discovery and introspection, including capabilities, requirements, signal routes, and schedules.
@spec name() :: String.t()
Returns the plugin's name.
@spec otp_app() :: atom() | nil
Returns the OTP application for config resolution.
@spec plugin_spec(map()) :: Jido.Plugin.Spec.t()
Returns the plugin specification with optional per-agent configuration.
Examples
spec = MyModule.plugin_spec(%{})
spec = MyModule.plugin_spec(%{custom_option: true})
@spec requires() :: [tuple()]
Returns the requirements for this plugin.
@spec schedules() :: [tuple()]
Returns the schedules for this plugin.
@spec schema() :: Zoi.schema() | nil
Returns the Zoi schema for plugin state.
@spec signal_patterns() :: [String.t()]
Returns the signal patterns this plugin handles.
@spec signal_routes() :: [tuple()]
Returns the signal routes for this plugin.
@spec singleton?() :: boolean()
Returns whether this plugin is a singleton.
@spec state_key() :: atom()
Returns the key used to store plugin state in the agent.
@spec subscriptions() :: [Jido.Plugin.sensor_subscription()]
Returns the sensor subscriptions for this plugin.
@spec tags() :: [String.t()]
Returns the plugin's tags.
@spec vsn() :: String.t() | nil
Returns the plugin's version.