Jido.Signal (Jido Signal v1.0.0)
View SourceDefines the core Signal structure in Jido, implementing the CloudEvents specification (v1.0.2) with Jido-specific extensions for agent-based systems.
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
- 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 eventtime
: Timestamp in ISO 8601 formatdatacontenttype
: Media type of the data (defaults to "application/json")dataschema
: Schema defining the data structuredata
: 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 dispatch config
{:ok, signal} = Signal.new(%{
type: "metrics.collected",
source: "/monitoring",
data: %{cpu: 80, memory: 70},
jido_dispatch: {:pubsub, topic: "metrics"}
})
Custom Signal Types
You can define custom Signal types using the use Jido.Signal
pattern:
defmodule MySignal do
use Jido.Signal,
type: "my.custom.signal",
default_source: "/my/service",
datacontenttype: "application/json",
schema: [
user_id: [type: :string, required: true],
message: [type: :string, required: true]
]
end
# Create instances
{:ok, signal} = MySignal.new(%{user_id: "123", message: "Hello"})
# Override runtime fields
{:ok, signal} = MySignal.new(
%{user_id: "123", message: "Hello"},
source: "/different/source",
subject: "user-notification",
jido_dispatch: {:pubsub, topic: "events"}
)
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 datatext/plain
- Unstructured textapplication/octet-stream
- Binary data- Custom MIME types for specific formats
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
Jido.Signal.Router
- Signal routingJido.Signal.Dispatch
- Dispatch handling- CloudEvents spec: https://cloudevents.io/
Summary
Functions
Defines a new Signal module.
Deserializes binary data back into a Signal struct or list of Signal structs.
Creates a new Signal struct from a map.
Converts a struct or list of structs to Signal data format.
Creates a new Signal struct.
Creates a new Signal struct, raising an error if invalid.
Serializes a Signal or a list of Signals using the specified or default serializer.
Legacy serialize function that returns binary directly (for backward compatibility).
Types
@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
Defines a new Signal module.
This macro sets up the necessary structure and callbacks for a custom Signal, including configuration validation and default implementations.
Options
:type
(String.t/0
) - Required. The type of the Signal:default_source
(String.t/0
) - The default source of the Signal:datacontenttype
(String.t/0
) - The content type of the data field:dataschema
(String.t/0
) - Schema URI for the data field (optional):schema
(keyword/0
) - A NimbleOptions schema for validating the Signal's data parameters The default value is[]
.
Examples
defmodule MySignal do
use Jido.Signal,
type: "my.custom.signal",
default_source: "/my/service",
schema: [
user_id: [type: :string, required: true],
message: [type: :string, required: true]
]
end
Deserializes binary data back into a Signal struct or list of Signal structs.
Parameters
binary
: The serialized binary data to deserializeopts
: Optional configuration including::serializer
- The serializer module to use (defaults to configured serializer):type
- Specific type to deserialize to:type_provider
- Custom type provider
Returns
{:ok, Signal.t() | list(Signal.t())}
if successful, {:error, reason}
otherwise
Examples
# JSON deserialization (default)
iex> json = ~s({"type":"example.event","source":"/example","id":"123"})
iex> {:ok, signal} = Jido.Signal.deserialize(json)
iex> signal.type
"example.event"
# Using a specific serializer
iex> {:ok, signal} = Jido.Signal.deserialize(binary, serializer: Jido.Signal.Serialization.ErlangTermSerializer)
iex> signal.type
"example.event"
# 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
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", ...}}
@spec map_to_signal_data([struct()], Keyword.t()) :: [t()]
@spec map_to_signal_data( struct(), Keyword.t() ) :: t()
Converts a struct or list of structs to Signal data format.
This function is useful for converting domain objects to Signal format while preserving their type information through the TypeProvider.
Parameters
signals
: A struct or list of structs to convertfields
: Additional fields to include (currently unused)
Returns
Signal struct or list of Signal structs with the original data as payload
Examples
# Converting a single struct
iex> user = %User{id: 1, name: "John"}
iex> signal = Jido.Signal.map_to_signal_data(user)
iex> signal.data
%User{id: 1, name: "John"}
# Converting multiple structs
iex> users = [%User{id: 1}, %User{id: 2}]
iex> signals = Jido.Signal.map_to_signal_data(users)
iex> length(signals)
2
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", ...}}
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", ...}
Serializes a Signal or a list of Signals using the specified or default serializer.
Parameters
signal_or_list
: A Signal struct or list of Signal structsopts
: Optional configuration including::serializer
- The serializer module to use (defaults to configured serializer)
Returns
{:ok, binary}
on success, {:error, reason}
on failure
Examples
iex> signal = %Jido.Signal{type: "example.event", source: "/example"}
iex> {:ok, binary} = Jido.Signal.serialize(signal)
iex> is_binary(binary)
true
# Using a specific serializer
iex> {:ok, binary} = Jido.Signal.serialize(signal, serializer: Jido.Signal.Serialization.ErlangTermSerializer)
iex> is_binary(binary)
true
# Serializing multiple Signals
iex> signals = [
...> %Jido.Signal{type: "event1", source: "/ex1"},
...> %Jido.Signal{type: "event2", source: "/ex2"}
...> ]
iex> {:ok, binary} = Jido.Signal.serialize(signals)
iex> is_binary(binary)
true
Legacy serialize function that returns binary directly (for backward compatibility).