hooks

package
v0.2.75 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package hooks runs user-supplied callbacks at points in an agent's lifecycle, and bundles related callbacks into named plugins.

A Hook observes or intervenes at one point. A Plugin is a named bundle of hooks shipped together — logging, policy enforcement, metrics, redaction — which is what "packaged cross-cutting behavior" means in practice. ADK draws the same distinction between its per-agent callbacks and its Runner-level plugins.

Where hooks run

BeforeTool   before a tool executes; can rewrite arguments or deny the call
AfterTool    after a tool returns; can rewrite the result
OnToolError  when a tool fails; can substitute a result and suppress the error

Tool hooks reach every LLM provider, because they attach to the tool set rather than to any provider's loop. See docs/tool-pipeline.md.

Denial

A denied tool call returns a message to the model rather than an error. The providers convert a tool error into a tool-result message and keep going, so returning an error would not stop anything -- it would just look like a tool that failed. A denial the model can read is more useful and more honest.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CommonSecretPatterns

func CommonSecretPatterns() []*regexp.Regexp

CommonSecretPatterns returns regexps for values that should not reach a model in a tool result.

Deliberately conservative: a pattern that over-matches corrupts legitimate output, which is its own failure.

Types

type AfterToolFunc

type AfterToolFunc func(ctx context.Context, call ToolCall, result string) (string, error)

AfterToolFunc runs after a tool returns and may rewrite the result.

type BeforeToolFunc

type BeforeToolFunc func(ctx context.Context, call ToolCall) (Outcome, error)

BeforeToolFunc runs before a tool executes.

type Decision

type Decision int

Decision is what a BeforeTool hook wants to happen.

const (
	// Allow lets the call proceed. This is the zero value, so a hook that
	// returns an empty Outcome allows by default rather than silently denying.
	Allow Decision = iota

	// Modify proceeds with rewritten arguments.
	Modify

	// Deny blocks the call and returns Message to the model instead.
	Deny
)

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics collects per-tool call counts, failures and durations.

func NewMetrics

func NewMetrics() *Metrics

NewMetrics creates a metrics collector.

func (*Metrics) Calls

func (m *Metrics) Calls() map[string]int

Calls returns how many times each tool was invoked.

func (*Metrics) Failures

func (m *Metrics) Failures() map[string]int

Failures returns how many times each tool failed.

func (*Metrics) Plugin

func (m *Metrics) Plugin() Plugin

Plugin returns the plugin that feeds this collector.

type OnToolErrorFunc

type OnToolErrorFunc func(ctx context.Context, call ToolCall, err error) (result string, handled bool)

OnToolErrorFunc runs when a tool fails. Returning handled=true substitutes the returned result and suppresses the error.

type Outcome

type Outcome struct {
	Decision Decision

	// Arguments replaces the call's arguments when Decision is Modify.
	Arguments string

	// Message is returned to the model when Decision is Deny.
	Message string
}

Outcome is a BeforeTool hook's verdict.

The zero value allows the call, which is deliberate: a hook that returns early, or one written before a new field existed, must not accidentally block every tool.

type Plugin

type Plugin struct {
	Name        string
	BeforeTool  BeforeToolFunc
	AfterTool   AfterToolFunc
	OnToolError OnToolErrorFunc
}

Plugin is a named bundle of hooks.

Name is required: it appears in panic recovery and error messages, and "which plugin denied this?" is unanswerable without it.

func AllowList

func AllowList(allowed ...string) Plugin

AllowList returns a plugin that denies any tool not named.

This is the smallest useful kill switch: an agent handed a broad tool set can be restricted per deployment without rebuilding the tool set.

func Logging

func Logging(log func(format string, args ...any)) Plugin

Logging returns a plugin that records every tool call and its outcome.

func Redact

func Redact(replacement string, patterns ...*regexp.Regexp) Plugin

Redact returns a plugin that masks matches in tool results before the model sees them.

Results are where secrets most often leak: a tool reads a config file or a log line and hands it straight to the model, which may then repeat it.

func RetryOnError

func RetryOnError() Plugin

RetryOnError returns a plugin that reports a tool failure to the model as a readable result instead of an error, so it can adapt rather than see an opaque failure.

func TruncateResults

func TruncateResults(maxBytes int) Plugin

TruncateResults returns a plugin that caps how much of a tool result reaches the model.

An unbounded tool result is the most common way a context window is blown: one directory listing or query dump can dwarf the conversation.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry holds the plugins an agent runs.

func NewRegistry

func NewRegistry(plugins ...Plugin) *Registry

NewRegistry creates an empty registry.

func (*Registry) Decorate

func (r *Registry) Decorate(agentName string) func([]interfaces.Tool) []interfaces.Tool

Decorate returns a tool decorator that applies this registry's hooks.

Pass it to agent.WithToolDecorator. Hooks then reach every provider, because the decorator attaches to the tool set rather than to any provider's loop.

func (*Registry) Describe

func (r *Registry) Describe() string

Describe renders a registry's plugins for logging or a status endpoint.

func (*Registry) Names

func (r *Registry) Names() []string

Names returns the registered plugin names, in order.

func (*Registry) Register

func (r *Registry) Register(p Plugin)

Register adds a plugin. Plugins run in registration order.

type ToolCall

type ToolCall struct {
	// Tool is the name of the tool being called.
	Tool string

	// Arguments is the raw JSON the model supplied.
	Arguments string

	// AgentName is the agent making the call, when known.
	AgentName string
}

ToolCall describes a tool invocation a hook may inspect or alter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL