Packages

Elixir port of Google's Agent Development Kit (ADK) — agent orchestration, sessions, tools, LLM abstraction, plugins, and telemetry. Transport-agnostic.

Current section

Files

Jump to
adk_ex lib adk plugin.ex
Raw

lib/adk/plugin.ex

defmodule ADK.Plugin do
@moduledoc """
Plugin struct for hooking into the agent lifecycle.
Plugins provide callbacks at Runner, Agent, Model, and Tool levels.
Callbacks follow the standard `{value | nil, updated_context}` pattern:
non-nil values short-circuit, nil continues to the next plugin/callback.
## Example
plugin = ADK.Plugin.new(
name: "logging",
before_model: fn cb_ctx, _request ->
IO.puts("Model called for \#{ADK.Agent.CallbackContext.agent_name(cb_ctx)}")
{nil, cb_ctx}
end
)
"""
alias ADK.Agent.{CallbackContext, InvocationContext}
alias ADK.Event
alias ADK.Model.LlmResponse
alias ADK.Tool.Context, as: ToolContext
alias ADK.Types.Content
@type on_user_message_callback ::
(InvocationContext.t(), Content.t() -> {Content.t() | nil, InvocationContext.t()})
@type before_run_callback ::
(InvocationContext.t() -> {Content.t() | nil, InvocationContext.t()})
@type after_run_callback :: (InvocationContext.t() -> :ok)
@type on_event_callback ::
(InvocationContext.t(), Event.t() -> {Event.t() | nil, InvocationContext.t()})
@type before_agent_callback ::
(CallbackContext.t() -> {Content.t() | nil, CallbackContext.t()})
@type after_agent_callback ::
(CallbackContext.t() -> {Content.t() | nil, CallbackContext.t()})
@type before_model_callback ::
(CallbackContext.t(), ADK.Model.LlmRequest.t() ->
{LlmResponse.t() | nil, CallbackContext.t()})
@type after_model_callback ::
(CallbackContext.t(), LlmResponse.t() -> {LlmResponse.t() | nil, CallbackContext.t()})
@type on_model_error_callback ::
(CallbackContext.t(), ADK.Model.LlmRequest.t(), term() ->
{LlmResponse.t() | nil, CallbackContext.t()})
@type before_tool_callback ::
(ToolContext.t(), struct(), map() -> {map() | nil, ToolContext.t()})
@type after_tool_callback ::
(ToolContext.t(), struct(), map(), map() -> {map() | nil, ToolContext.t()})
@type on_tool_error_callback ::
(ToolContext.t(), struct(), map() -> {map() | nil, ToolContext.t()})
@type t :: %__MODULE__{
name: String.t(),
on_user_message: on_user_message_callback() | nil,
on_event: on_event_callback() | nil,
before_run: before_run_callback() | nil,
after_run: after_run_callback() | nil,
before_agent: before_agent_callback() | nil,
after_agent: after_agent_callback() | nil,
before_model: before_model_callback() | nil,
after_model: after_model_callback() | nil,
on_model_error: on_model_error_callback() | nil,
before_tool: before_tool_callback() | nil,
after_tool: after_tool_callback() | nil,
on_tool_error: on_tool_error_callback() | nil
}
@enforce_keys [:name]
defstruct [
:name,
:on_user_message,
:on_event,
:before_run,
:after_run,
:before_agent,
:after_agent,
:before_model,
:after_model,
:on_model_error,
:before_tool,
:after_tool,
:on_tool_error
]
@doc """
Creates a new plugin from keyword options.
Requires `:name`. All callback fields are optional (default nil).
"""
@spec new(keyword()) :: t()
def new(opts) do
struct!(__MODULE__, opts)
end
end