BB.Jido.Plugin.Robot (bb_jido v0.2.0)

Copy Markdown View Source

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, and BB.Jido.Action.GetJointState.
  • Default signal routes for the canonical bb.* signal types, including routes that keep the plugin state current: bb.state.transition is routed to BB.Jido.Action.UpdateSafetyState and bb.safety.error to BB.Jido.Action.RecordSafetyError.
  • Plugin-owned state under agent.state.robot: the configured :robot module, a cached :safety_state (updated by the routed UpdateSafetyState action whenever a safety transition arrives), the :last_safety_error (updated by RecordSafetyError when the [:safety, :error] topic is bridged), and :last_joint_state (updated whenever GetJointState runs).
  • A supervised BB.Jido.PubSubBridge mounted 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_actions are 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 of BB.PubSub paths 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 via prepare_action/3 unless BB.Safety.state/1 reports :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]}}
    ]
end

The 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

__plugin_metadata__()

@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.

actions()

@spec actions() :: [module()]

Returns the list of action modules provided by this plugin.

capabilities()

@spec capabilities() :: [atom()]

Returns the capabilities provided by this plugin.

category()

@spec category() :: String.t() | nil

Returns the plugin's category.

config_schema()

@spec config_schema() :: Zoi.schema() | nil

Returns the Zoi schema for per-agent configuration.

description()

@spec description() :: String.t() | nil

Returns the plugin's description.

manifest()

@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.

name()

@spec name() :: String.t()

Returns the plugin's name.

otp_app()

@spec otp_app() :: atom() | nil

Returns the OTP application for config resolution.

plugin_spec(config \\ %{})

@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})

requires()

@spec requires() :: [tuple()]

Returns the requirements for this plugin.

schedules()

@spec schedules() :: [tuple()]

Returns the schedules for this plugin.

schema()

@spec schema() :: Zoi.schema() | nil

Returns the Zoi schema for plugin state.

signal_patterns()

@spec signal_patterns() :: [String.t()]

Returns the signal patterns this plugin handles.

signal_routes()

@spec signal_routes() :: [tuple()]

Returns the signal routes for this plugin.

singleton?()

@spec singleton?() :: boolean()

Returns whether this plugin is a singleton.

state_key()

@spec state_key() :: atom()

Returns the key used to store plugin state in the agent.

subscriptions()

@spec subscriptions() :: [Jido.Plugin.sensor_subscription()]

Returns the sensor subscriptions for this plugin.

tags()

@spec tags() :: [String.t()]

Returns the plugin's tags.

vsn()

@spec vsn() :: String.t() | nil

Returns the plugin's version.