ADK.Callback behaviour (ADK v0.0.1)

Copy Markdown View Source

Callback hooks for agent, model, and tool invocations.

Callbacks allow intercepting and transforming execution at key points in the agent pipeline. Each callback receives a callback context and can either continue execution or halt it early.

Callback Types

  • before_agent/1 — called before an agent runs; can short-circuit with {:halt, events}
  • after_agent/2 — called after an agent runs; can transform the resulting events
  • before_model/1 — called before an LLM call; can short-circuit with {:halt, response}
  • after_model/2 — called after an LLM call; can transform the response
  • before_tool/1 — called before a tool runs; can short-circuit with {:halt, result}
  • after_tool/2 — called after a tool runs; can transform the result

Usage

defmodule MyCallbacks do
  @behaviour ADK.Callback

  @impl true
  def before_agent(callback_ctx), do: {:cont, callback_ctx}

  @impl true
  def after_agent(events, _callback_ctx), do: events
end

# Pass callbacks to Runner.run/5
ADK.Runner.run(runner, user_id, session_id, message, callbacks: [MyCallbacks])

Summary

Callbacks

Called after an agent executes. Receives the events and callback context; returns (possibly transformed) events.

Called after a model call. Receives the response and callback context; returns (possibly transformed) response.

Called after a tool executes. Receives the result and callback context; returns (possibly transformed) result.

Called before an agent executes. Return {:cont, callback_ctx} to continue or {:halt, events} to short-circuit.

Called before a model call. Return {:cont, callback_ctx} to continue or {:halt, {:ok, response}} to short-circuit.

Called before a tool executes. Return {:cont, callback_ctx} to continue or {:halt, result} to short-circuit.

Called when the LLM backend returns an error.

Called when a tool returns an error.

Functions

Run a list of "after" callbacks in order, threading the result through each.

Run a list of "before" callbacks in order. Returns {:cont, callback_ctx} if all callbacks continue, or {:halt, result} on the first halt.

Run on_model_error callbacks. Returns {:retry, callback_ctx}, {:fallback, {:ok, response}}, or {:error, reason}. First callback to return non-error wins.

Run on_tool_error callbacks. Returns {:retry, callback_ctx}, {:fallback, {:ok, result}}, or {:error, reason}. First callback to return non-error wins.

Types

callback_ctx()

@type callback_ctx() :: %{
  :agent => any(),
  :context => ADK.Context.t(),
  optional(:request) => map(),
  optional(:tool) => map(),
  optional(:tool_args) => map()
}

Callbacks

after_agent(list, callback_ctx)

(optional)
@callback after_agent([ADK.Event.t()], callback_ctx()) :: [ADK.Event.t()]

Called after an agent executes. Receives the events and callback context; returns (possibly transformed) events.

after_model(arg1, callback_ctx)

(optional)
@callback after_model({:ok, map()} | {:error, term()}, callback_ctx()) ::
  {:ok, map()} | {:error, term()}

Called after a model call. Receives the response and callback context; returns (possibly transformed) response.

after_tool(result, callback_ctx)

(optional)
@callback after_tool(ADK.Tool.result(), callback_ctx()) :: ADK.Tool.result()

Called after a tool executes. Receives the result and callback context; returns (possibly transformed) result.

before_agent(callback_ctx)

(optional)
@callback before_agent(callback_ctx()) ::
  {:cont, callback_ctx()} | {:halt, [ADK.Event.t()]}

Called before an agent executes. Return {:cont, callback_ctx} to continue or {:halt, events} to short-circuit.

before_model(callback_ctx)

(optional)
@callback before_model(callback_ctx()) ::
  {:cont, callback_ctx()} | {:halt, {:ok, map()} | {:error, term()}}

Called before a model call. Return {:cont, callback_ctx} to continue or {:halt, {:ok, response}} to short-circuit.

before_tool(callback_ctx)

(optional)
@callback before_tool(callback_ctx()) ::
  {:cont, callback_ctx()} | {:halt, ADK.Tool.result()}

Called before a tool executes. Return {:cont, callback_ctx} to continue or {:halt, result} to short-circuit.

on_model_error({}, callback_ctx)

(optional)
@callback on_model_error(
  {:error, term()},
  callback_ctx()
) :: {:retry, callback_ctx()} | {:fallback, {:ok, map()}} | {:error, term()}

Called when the LLM backend returns an error.

Return one of:

  • {:retry, callback_ctx} — retry the LLM call
  • {:fallback, {:ok, response}} — use a fallback response
  • {:error, reason} — propagate the error (re-raise)

on_tool_error({}, callback_ctx)

(optional)
@callback on_tool_error(
  {:error, term()},
  callback_ctx()
) :: {:retry, callback_ctx()} | {:fallback, {:ok, term()}} | {:error, term()}

Called when a tool returns an error.

Return one of:

  • {:retry, callback_ctx} — retry the tool call
  • {:fallback, {:ok, result}} — use a fallback result
  • {:error, reason} — propagate the error

Functions

run_after(callbacks, hook, result, callback_ctx)

@spec run_after([module()], atom(), term(), callback_ctx()) :: term()

Run a list of "after" callbacks in order, threading the result through each.

run_before(callbacks, hook, callback_ctx)

@spec run_before([module()], atom(), callback_ctx()) ::
  {:cont, callback_ctx()} | {:halt, term()}

Run a list of "before" callbacks in order. Returns {:cont, callback_ctx} if all callbacks continue, or {:halt, result} on the first halt.

run_on_error(callbacks, error, callback_ctx)

@spec run_on_error([module()], {:error, term()}, callback_ctx()) ::
  {:retry, callback_ctx()} | {:fallback, {:ok, map()}} | {:error, term()}

Run on_model_error callbacks. Returns {:retry, callback_ctx}, {:fallback, {:ok, response}}, or {:error, reason}. First callback to return non-error wins.

run_on_tool_error(callbacks, error, callback_ctx)

@spec run_on_tool_error([module()], {:error, term()}, callback_ctx()) ::
  {:retry, callback_ctx()} | {:fallback, {:ok, term()}} | {:error, term()}

Run on_tool_error callbacks. Returns {:retry, callback_ctx}, {:fallback, {:ok, result}}, or {:error, reason}. First callback to return non-error wins.