AgentForge (AgentForge v0.2.2)
View SourceAgentForge is a lightweight, signal-driven workflow framework designed for personal projects.
Key Features
- Signal-based communication
- Composable handler pipelines
- Persistent state management
- Debug tracing support
Example
# Define a simple handler
message_handler = fn signal, state ->
new_state = Map.put(state, :last_message, signal.data)
{AgentForge.Signal.emit(:processed, "Got: #{signal.data}"), new_state}
end
# Create a flow with the handler
flow = AgentForge.new_flow([message_handler], debug: true)
# Execute the flow with a signal
{:ok, result, _state} = flow.(AgentForge.Signal.new(:message, "Hello"))
# result.data will be "Got: Hello"
Summary
Functions
Gets statistics from the last flow execution. Returns nil if no flow has been executed yet or statistics collection was disabled.
Creates a new flow with the given handlers and options. Returns a function that can be used to execute the flow.
Creates a new stateful flow that maintains state between executions. Similar to new_flow/2 but automatically stores and retrieves state.
Processes a flow with execution limits. This can prevent long-running operations.
Functions
Gets statistics from the last flow execution. Returns nil if no flow has been executed yet or statistics collection was disabled.
Examples
iex> handlers = [fn signal, state -> {{:emit, signal}, state} end]
iex> signal = AgentForge.Signal.new(:test, "data")
iex> {:ok, _, _} = AgentForge.process_with_limits(handlers, signal, %{})
iex> stats = AgentForge.get_last_execution_stats()
iex> stats.steps
1
Creates a new flow with the given handlers and options. Returns a function that can be used to execute the flow.
Options
All options from AgentForge.Runtime.execute/3
are supported.
Examples
iex> handler = fn signal, state ->
...> {AgentForge.Signal.emit(:echo, signal.data), state}
...> end
iex> flow = AgentForge.new_flow([handler])
iex> {:ok, result, _} = flow.(AgentForge.Signal.new(:test, "hello"))
iex> result.data
"hello"
Creates a new stateful flow that maintains state between executions. Similar to new_flow/2 but automatically stores and retrieves state.
Examples
iex> {:ok, _pid} = AgentForge.Store.start_link(name: :test_store)
iex> counter = fn _signal, state ->
...> count = Map.get(state, :count, 0) + 1
...> {AgentForge.Signal.emit(:count, count), Map.put(state, :count, count)}
...> end
iex> flow = AgentForge.new_stateful_flow([counter], store_name: :test_store)
iex> {:ok, result1, _} = flow.(AgentForge.Signal.new(:inc, nil))
iex> {:ok, result2, _} = flow.(AgentForge.Signal.new(:inc, nil))
iex> result2.data > result1.data
true
@spec process_with_limits( [function()], AgentForge.Signal.t(), map(), keyword() ) :: {:ok, AgentForge.Signal.t() | term(), term()} | {:ok, AgentForge.Signal.t() | term(), term(), AgentForge.ExecutionStats.t()} | {:error, term(), term()} | {:error, term(), term(), AgentForge.ExecutionStats.t()}
Processes a flow with execution limits. This can prevent long-running operations.
Options
:timeout_ms
- Maximum execution time in milliseconds (default: 30000):collect_stats
- Whether to collect execution statistics (default: true):return_stats
- Whether to return statistics in the result (default: false)
Examples
iex> handlers = [
...> fn _signal, state -> {{:emit, AgentForge.Signal.new(:done, "Success")}, state} end
...> ]
iex> {:ok, result, _} = AgentForge.process_with_limits(handlers, AgentForge.Signal.new(:test, "data"), %{})
iex> result.data
"Success"