Skip to content

Repository files navigation

Beam Bots Logo

BB.Jido

CI License: Apache 2.0 Hex version badge Hexdocs badge REUSE status Ask DeepWiki

Autonomous agents for Beam Bots, built on the Jido agent framework.

Where bb_reactor answers "how do I execute this workflow?", bb_jido lets you answer "what should I do next to achieve this goal?" — your robot becomes a goal-directed agent that observes the world via BB.PubSub and dispatches commands or workflows in response.

Layered architecture

┌─────────────────────────────────────────────────┐
│  Jido Agent                                     │
│  - Observes via BB.PubSub (bridged to signals)  │
│  - Routes signals to actions                    │
│  - Emits further signals as directives          │
├─────────────────────────────────────────────────┤
│  bb_reactor workflows  +  BB commands           │
│  (executed via BB.Jido.Action.Reactor and       │
│   BB.Jido.Action.Command)                       │
└─────────────────────────────────────────────────┘

What's in the box

Module Purpose
BB.Jido.Plugin.Robot Jido v2 plugin you attach to an agent — adds robot state, the standard actions, default bb.* signal routes, and the PubSub bridge
BB.Jido.Action.Command Run a BB command (apply(robot, command, [goal])) and await its result
BB.Jido.Action.Reactor Run a bb_reactor workflow with the robot bound into context.private.bb_robot
BB.Jido.Action.WaitForState Wait for the robot state machine to enter a target state
BB.Jido.Action.GetJointState Read current joint positions/velocities
BB.Jido.Action.SafetyAware Mixin that aborts an action with {:safety_not_armed, state} unless the robot is armed
BB.Jido.PubSubBridge GenServer that forwards {:bb, path, %BB.Message{}} messages into an agent as Jido.Signals
BB.Jido.Signal Canonical BB.MessageJido.Signal mapping (CloudEvents bb.* namespace)
BB.Jido.Telemetry Telemetry spans for actions and a per-signal counter

Installation

The fastest path is via Igniter — it adds the dep, generates a Jido instance module, and wires it into your application supervision tree in one command:

mix igniter.install bb_jido --robot MyApp.Robot

With --robot, it also scaffolds an agent module that attaches BB.Jido.Plugin.Robot for that robot. Drop the flag to skip the agent and add it later with mix bb_jido.add_agent.

bb_reactor is not a hard dependency. If you want to use BB.Jido.Action.Reactor, add it the same way:

mix igniter.install bb_reactor

See the scaffolding how-to for the full list of generators.

Quick start

After mix igniter.install bb_jido --robot MyApp.Robot, you'll have:

  • lib/my_app/jido.exuse Jido, otp_app: :my_app
  • lib/my_app/robot/agent.ex — agent with the robot plugin attached
  • lib/my_app/application.ex — children list gains {Jido, [name: MyApp.Jido]}

Start the agent and send it a signal:

{:ok, pid} = Jido.start_agent(MyApp.Jido, MyApp.Robot.Agent, id: "main")

:ok =
  Jido.AgentServer.cast(
    pid,
    Jido.Signal.new!(
      "bb.command.execute",
      %{robot: MyApp.Robot, command: :home, goal: %{}}
    )
  )

Signals

The PubSub bridge maps BB.PubSub events into Jido signals with a stable naming scheme:

Signal type Source
bb.state.transition [:state_machine] topic, %BB.StateMachine.Transition{} payloads
bb.safety.error [:safety, :error] topic, %BB.Safety.HardwareError{} payloads
bb.parameter.changed [:param | path] topics, %BB.Parameter.Changed{} payloads
bb.pubsub.<path> Anything else — dotted source path (e.g. bb.pubsub.sensor.joint_state)

The source URI is /bb/<robot module> for traceability. Payload, path, and robot are all available under signal.data.

By default the bridge only subscribes to [:state_machine]. Pass :topics (and optionally :message_types or :throttle_ms) when attaching the plugin to opt into higher-volume topics:

plugins: [
  {BB.Jido.Plugin.Robot,
   %{robot: MyRobot,
     topics: [[:state_machine], [:sensor, :joint_state]],
     throttle_ms: 100}}
]

Error taxonomy

Actions return a consistent tagged-error set:

  • {:error, :safety_disarmed} — command rejected (or stopped) because the robot was disarmed
  • {:error, {:command_failed, reason}} — any other command failure
  • {:error, {:reactor_failed, errors}} — reactor returned errors
  • {:error, {:reactor_halted, reason}} — reactor was halted mid-flight
  • {:error, :timeout}WaitForState ran out of time
  • {:error, {:subscribe_failed, reason}}WaitForState couldn't subscribe to the state topic
  • {:error, {:wait_failed, reason}}WaitForState's temporary subscriber process exited abnormally
  • {:error, {:safety_not_armed, state}}BB.Jido.Action.SafetyAware guard tripped
  • {:error, :robot_not_specified}SafetyAware found no robot in params or context

See the error taxonomy reference for the full matching guide.

Documentation

Full documentation is available at HexDocs.

About

Autonomous agents for Beam Bots with Jido

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages