Raxol.Agent.CommandHook behaviour (Raxol Agent v2.6.0)

Copy Markdown View Source

Pre/post execution hooks for agent commands.

Hooks can inspect, modify, or deny commands before and after execution. This enables audit logging, permission checks, rate limiting, and other cross-cutting concerns without modifying individual agent modules.

Usage

Define a hook module:

defmodule MyAuditHook do
  @behaviour Raxol.Agent.CommandHook

  @impl true
  def pre_execute(command, context) do
    Logger.info("Executing: #{inspect(command.type)}")
    {:ok, command}
  end

  @impl true
  def post_execute(command, result, context) do
    Logger.info("Result: #{inspect(result)}")
    {:ok, result}
  end
end

Register hooks when starting an agent:

Agent.Session.start_link(
  id: :my_agent,
  app_module: MyAgent,
  hooks: [MyAuditHook, MyPermissionHook]
)

Hook Results

  • {:ok, command} -- allow (optionally modified)
  • {:deny, reason} -- block execution, send denial as command result
  • {:ok, result} -- post-hook, optionally modify result

Summary

Callbacks

Called after a command has been executed.

Called before a command is executed.

Functions

Run a result through a chain of post-execution hooks.

Run a command through a chain of pre-execution hooks.

Wrap a list of directives, applying pre/post hooks around each execution.

Types

effect()

@type effect() :: Raxol.Agent.Directive.t()

hook_context()

@type hook_context() :: %{agent_id: term(), agent_module: module()}

post_result()

@type post_result() :: {:ok, term()} | {:error, term()}

pre_result()

@type pre_result() :: {:ok, effect()} | {:deny, term()}

Callbacks

post_execute(command, result, context)

(optional)
@callback post_execute(
  command :: effect(),
  result :: term(),
  context :: hook_context()
) :: post_result()

Called after a command has been executed.

Return {:ok, result} to pass through (optionally modify the result).

pre_execute(command, context)

@callback pre_execute(command :: effect(), context :: hook_context()) :: pre_result()

Called before a command is executed.

Return {:ok, command} to allow (optionally modify the command), or {:deny, reason} to block execution.

Functions

run_post_hooks(list, command, result, context)

@spec run_post_hooks([module()], effect(), term(), hook_context()) :: post_result()

Run a result through a chain of post-execution hooks.

Hooks are evaluated in order. Each hook may modify the result.

run_pre_hooks(list, command, context)

@spec run_pre_hooks([module()], effect(), hook_context()) :: pre_result()

Run a command through a chain of pre-execution hooks.

Hooks are evaluated in order. The first :deny short-circuits the chain. Each hook may modify the command before passing it to the next.

wrap_commands(commands, hooks, context)

@spec wrap_commands([effect()], [module()], hook_context()) :: [effect()]

Wrap a list of directives, applying pre/post hooks around each execution.

Returns a new list where hookable directives (Async, Shell, SendAgent) are wrapped to run hooks. Other directives pass through unchanged.

Denied directives are replaced with an Async directive that sends a {:command_denied, type, reason} result back to the agent.