Jido.Signal (Jido v1.1.0-rc.2)

View Source

Defines the core Signal structure in Jido, implementing the CloudEvents specification (v1.0.2) with Jido-specific extensions for agent-based systems.

https://cloudevents.io/

Overview

Signals are the universal message format in Jido, serving as the nervous system of your agent-based application. Every event, command, and state change flows through the system as a Signal, providing:

  • Standardized event structure (CloudEvents v1.0.2 compatible)
  • Rich metadata and context tracking
  • Built-in instruction handling
  • Flexible dispatch configuration
  • Automatic serialization

CloudEvents Compliance

Each Signal implements the CloudEvents v1.0.2 specification with these required fields:

  • specversion: Always "1.0.2"
  • id: Unique identifier (UUID v4)
  • source: Origin of the event ("/service/component")
  • type: Classification of the event ("domain.entity.action")

And optional fields:

  • subject: Specific subject of the event
  • time: Timestamp in ISO 8601 format
  • datacontenttype: Media type of the data (defaults to "application/json")
  • dataschema: Schema defining the data structure
  • data: The actual event payload

Jido Extensions

Beyond the CloudEvents spec, Signals include Jido-specific fields:

  • jido_dispatch: Routing and delivery configuration (optional)

Creating Signals

Signals can be created in several ways:

# Basic event
{:ok, signal} = Signal.new(%{
  type: "user.created",
  source: "/auth/registration",
  data: %{user_id: "123", email: "user@example.com"}
})

# With instructions
{:ok, signal} = Signal.new(%{
  type: "order.process",
  source: "/orders",
  data: %{order_id: "456"},
  jido_instructions: [
    ProcessOrder,
    {NotifyUser, %{template: "order_confirmation"}}
  ]
})

# With dispatch config
{:ok, signal} = Signal.new(%{
  type: "metrics.collected",
  source: "/monitoring",
  data: %{cpu: 80, memory: 70},
  jido_dispatch: {:pubsub, topic: "metrics"}
})

Signal Types

Signal types are strings, but typically use a hierarchical dot notation:

<domain>.<entity>.<action>[.<qualifier>]

Examples:

  • user.profile.updated
  • order.payment.processed.success
  • system.metrics.collected

Guidelines for type naming:

  • Use lowercase with dots
  • Keep segments meaningful
  • Order from general to specific
  • Include qualifiers when needed

Data Content Types

The datacontenttype field indicates the format of the data field:

  • application/json (default) - JSON-structured data
  • text/plain - Unstructured text
  • application/octet-stream - Binary data
  • Custom MIME types for specific formats

Instruction Handling

Signals can carry instructions for agents to execute:

Signal.new(%{
  type: "task.assigned",
  source: "/action",
  jido_instructions: [
    ValidateTask,
    {AssignTask, %{worker: "agent_1"}},
    NotifyAssignment
  ]
})

Instructions are normalized and validated during Signal creation.

Dispatch Configuration

The jido_dispatch field controls how the Signal is delivered:

# Single dispatch config
jido_dispatch: {:pubsub, topic: "events"}

# Multiple dispatch targets
jido_dispatch: [
  {:pubsub, topic: "events"},
  {:logger, level: :info},
  {:webhook, url: "https://api.example.com/webhook"}
]

See Also

Summary

Functions

Deserializes a JSON string back into a Signal struct or list of Signal structs.

Creates a new Signal struct from a map.

Creates a new Signal struct.

Creates a new Signal struct, raising an error if invalid.

Serializes a Signal or a list of Signals to JSON string.

Types

t()

@type t() :: %Jido.Signal{
  data: term() | nil,
  datacontenttype: String.t() | nil,
  dataschema: String.t() | nil,
  id: String.t(),
  jido_dispatch: Jido.Signal.Dispatch.dispatch_configs() | nil,
  source: String.t(),
  specversion: String.t(),
  subject: String.t() | nil,
  time: String.t() | nil,
  type: String.t()
}

Functions

deserialize(json)

@spec deserialize(binary()) :: {:ok, t() | [t()]} | {:error, term()}

Deserializes a JSON string back into a Signal struct or list of Signal structs.

Parameters

  • json: The JSON string to deserialize

Returns

{:ok, Signal.t() | list(Signal.t())} if successful, {:error, reason} otherwise

Examples

iex> json = ~s({"type":"example.event","source":"/example","id":"123"})
iex> {:ok, signal} = Jido.Signal.deserialize(json)
iex> signal.type
"example.event"

iex> # Deserializing multiple Signals
iex> json = ~s([{"type":"event1","source":"/ex1"},{"type":"event2","source":"/ex2"}])
iex> {:ok, signals} = Jido.Signal.deserialize(json)
iex> length(signals)
2

from_map(map)

@spec from_map(map()) :: {:ok, t()} | {:error, String.t()}

Creates a new Signal struct from a map.

Parameters

  • map: A map containing the Signal attributes.

Returns

{:ok, Signal.t()} if the map is valid, {:error, String.t()} otherwise.

Examples

iex> Jido.Signal.from_map(%{"type" => "example.event", "source" => "/example", "id" => "123"})
{:ok, %Jido.Signal{type: "example.event", source: "/example", id: "123", ...}}

map_to_signal_data(signals, fields \\ [])

@spec map_to_signal_data([struct()], Keyword.t()) :: [t()]
@spec map_to_signal_data(
  struct(),
  Keyword.t()
) :: t()

new(attrs)

@spec new(map() | keyword()) :: {:ok, t()} | {:error, String.t()}

Creates a new Signal struct.

Parameters

  • attrs: A map or keyword list containing the Signal attributes.

Returns

{:ok, Signal.t()} if the attributes are valid, {:error, String.t()} otherwise.

Examples

iex> Jido.Signal.new(%{type: "example.event", source: "/example", id: "123"})
{:ok, %Jido.Signal{type: "example.event", source: "/example", id: "123", ...}}

iex> Jido.Signal.new(type: "example.event", source: "/example")
{:ok, %Jido.Signal{type: "example.event", source: "/example", ...}}

new!(attrs)

@spec new!(map() | keyword()) :: t() | no_return()

Creates a new Signal struct, raising an error if invalid.

Parameters

  • attrs: A map or keyword list containing the Signal attributes.

Returns

Signal.t() if the attributes are valid.

Raises

RuntimeError if the attributes are invalid.

Examples

iex> Jido.Signal.new!(%{type: "example.event", source: "/example"})
%Jido.Signal{type: "example.event", source: "/example", ...}

iex> Jido.Signal.new!(type: "example.event", source: "/example")
%Jido.Signal{type: "example.event", source: "/example", ...}

serialize(signal)

@spec serialize(t() | [t()]) :: binary()

Serializes a Signal or a list of Signals to JSON string.

Parameters

  • signal_or_list: A Signal struct or list of Signal structs

Returns

A JSON string representing the Signal(s)

Examples

iex> signal = %Jido.Signal{type: "example.event", source: "/example"}
iex> json = Jido.Signal.serialize(signal)
iex> is_binary(json)
true

iex> # Serializing multiple Signals
iex> signals = [
...>   %Jido.Signal{type: "event1", source: "/ex1"},
...>   %Jido.Signal{type: "event2", source: "/ex2"}
...> ]
iex> json = Jido.Signal.serialize(signals)
iex> is_binary(json)
true