Agent Signal Output Guide
View SourceOverview
Agent signal output provides a comprehensive event and error emission system for tracking agent execution, state changes, and instruction results. The output system ensures consistent monitoring and traceability across your agent-based applications.
Output Types
1. Event Signals
Event signals track lifecycle and state transition events within the agent system. Events follow the pattern jido.agent.event.<category>.<action>
.
Common event categories include:
Process Events
# Process lifecycle events
"jido.agent.event.process.started" # Process started successfully
"jido.agent.event.process.terminated" # Process terminated normally
"jido.agent.event.process.failed" # Process failed to start/execute
"jido.agent.event.process.restarted" # Process was restarted
State Transition Events
"jido.agent.event.transition.succeeded" # State transition completed
"jido.agent.event.transition.failed" # State transition failed
Queue Management Events
"jido.agent.event.queue.overflow" # Queue size exceeded maximum
"jido.agent.event.queue.cleared" # Queue was emptied
2. Error Signals
Error signals provide detailed error reporting when operations fail. They follow the pattern jido.agent.err.<category>.<type>
.
# Common error signal types
"jido.agent.err.execution.error" # Runtime execution errors
"jido.agent.err.validation.error" # State/parameter validation errors
"jido.agent.err.directive.error" # Directive application errors
Error signals include:
- Detailed error message
- Error context and metadata
- Stack trace when available
- Related entity IDs (agent, process, etc.)
3. Signal Output
Signal output represents the results of processing incoming signals. These follow the pattern jido.agent.out.signal.<result>
.
# Signal output types
"jido.agent.out.signal.result" # Final signal processing result
"jido.agent.out.signal.processed" # Signal successfully processed
"jido.agent.out.signal.rejected" # Signal rejected/invalid
4. Instruction Output
Instruction output tracks the execution results of individual instructions. These follow the pattern jido.agent.out.instruction.<result>
.
# Instruction output example
"jido.agent.out.instruction.result" # Individual instruction result
Important: When a signal triggers multiple instructions, each instruction generates its own output signal. This provides granular visibility into the execution flow.
Output Structure
All output signals contain consistent base fields:
%{
id: "sig_abc123", # Unique signal ID
type: "jido.agent.<type>", # Signal type
source: "agent:worker_1", # Signal origin
subject: "jido://agent/worker_1/abc123", # Subject URI
time: "2024-02-11T12:00:00Z", # ISO 8601 timestamp
data: %{ # Signal-specific payload
result: "success",
details: %{...}
}
}
Signal Subject Format
The subject
field follows a specific URI format for signals emitted by Jido agents:
"jido://agent/<agent_name>/<agent_id>"
For example:
- Named agent:
"jido://agent/data_processor/abc123"
- Anonymous agent:
"jido://agent/abc123"
(when no name is specified)
This subject field is automatically set by the agent when emitting signals, ensuring consistent identification and routing. The agent's name and ID are preserved across all signals it emits, making it easier to:
- Track signal chains through the system
- Filter and route signals by agent
- Associate related events and outputs
- Debug issues across distributed deployments
Example Flow
Here's how different output types work together during execution:
# 1. Agent receives signal with multiple instructions
signal = %Signal{
type: "process.data",
data: %{items: [1, 2, 3]}
}
# 2. Event signals emitted for processing
"jido.agent.event.started" # Agent starts processing
"jido.agent.event.transition.succeeded" # State transition to :running
# 3. Individual instruction outputs
"jido.agent.out.instruction.result" # ValidateData result
"jido.agent.out.instruction.result" # ProcessItems result
"jido.agent.out.instruction.result" # SaveResults result
# 4. Final signal output
"jido.agent.out.signal.result" # Overall processing result
# 5. Completion events
"jido.agent.event.transition.succeeded" # State transition to :idle
Best Practices
1. Output Handling
- Subscribe to relevant output types based on monitoring needs
- Implement proper error handling for each output type
- Consider output persistence for audit trails
- Use structured logging for output signals
2. Signal Design
- Keep payloads focused and relevant
- Include necessary context in metadata
- Use consistent naming conventions
- Follow type-specific patterns
3. Monitoring
- Track error rates by type
- Monitor queue sizes and overflow events
- Alert on critical state transitions
- Analyze instruction completion patterns
- Set up dashboards for key metrics
4. Error Handling
# Implement comprehensive error handling
case handle_signal(signal) do
{:ok, result} ->
# Normal output handling
emit_output("jido.agent.out.signal.result", result)
{:error, reason} ->
# Error output handling
emit_error("jido.agent.err.execution.error", %{
reason: reason,
signal_id: signal.id,
context: get_error_context()
})
end
Testing Output
defmodule OutputTest do
use ExUnit.Case
test "emits instruction results" do
{:ok, agent} = MyAgent.new()
# Execute multi-instruction signal
{:ok, _result} = MyAgent.process([
ValidateAction,
ProcessAction,
SaveAction
])
# Assert output signals
assert_receive {:signal, %{type: "jido.agent.out.instruction.result"}}
assert_receive {:signal, %{type: "jido.agent.out.instruction.result"}}
assert_receive {:signal, %{type: "jido.agent.out.instruction.result"}}
end
test "handles errors appropriately" do
{:ok, agent} = MyAgent.new()
# Trigger error condition
{:error, _reason} = MyAgent.process(InvalidAction)
# Assert error output
assert_receive {:signal, %{
type: "jido.agent.err.execution.error",
data: %{reason: :invalid_action}
}}
end
end