Documentation
¶
Index ¶
- Constants
- Variables
- func CallIDFromContext(ctx context.Context) (string, bool)
- func Register(r *resource.Registry) error
- func WithCallID(ctx context.Context, id string) context.Context
- func WithSession(ctx context.Context, s Session) context.Context
- type Assembly
- func (a *Assembly) Catalog() Catalog
- func (a *Assembly) Close() error
- func (a *Assembly) Dispatcher() Dispatcher
- func (a *Assembly) Execute(ctx context.Context, call message.ToolCall) message.ToolResult
- func (a *Assembly) ExecuteAll(ctx context.Context, calls []message.ToolCall) []message.ToolResult
- func (a *Assembly) NewSession() Session
- type AssemblyFactory
- type AssemblyOption
- type AssemblySettings
- type Budget
- type Catalog
- type ConflictPolicy
- type Dispatch
- type Dispatcher
- type Executor
- type Exposure
- type LazyTool
- type Middleware
- type Option
- type Policy
- type Registrar
- type Registry
- type RegistryAttacher
- type RegistryFactory
- type SearchHit
- type SearchTool
- type Session
- type Source
- type Tool
- type ToolMeta
- type ToolMetadata
Constants ¶
const AssemblyKind = "tool.Assembly"
AssemblyKind is the deployment resource kind of the standard tool assembly (registry + executor + optional dynamic injection).
const RegistryKind = "tool.Registry"
RegistryKind is the deployment resource kind of a tool registry.
const ToolName = "tool_search"
ToolName is the built-in tool_search tool name. The assembly registers it with ExposureAlways when dynamic injection is enabled, so the model always has a discovery path.
Variables ¶
var DefaultBudget = Budget{
MaxDefinitions: 32,
MaxBytes: 16 * 1024,
}
DefaultBudget is the built-in budget: 32 tools or 16 KiB of definitions per turn, whichever is hit first.
Functions ¶
func CallIDFromContext ¶ added in v0.1.30
CallIDFromContext returns the active tool call id carried by ctx. ok=false means the caller is outside a tool execution (or the id was empty); consumers should treat the zero value as "unknown" rather than an error.
func WithCallID ¶ added in v0.1.30
WithCallID returns a derived context carrying id as the active tool call id.
Types ¶
type Assembly ¶
type Assembly struct {
// contains filtered or unexported fields
}
Assembly is the standard tool resource value: the aggregated registry (read surface), the executor (execution surface), and — when dynamic injection is configured — the injection policy that session views are created from.
func NewAssembly ¶
func NewAssembly(sources []Source, opts ...AssemblyOption) (*Assembly, error)
NewAssembly builds an assembly from sources. With dynamic enabled, the built-in tool_search tool is appended as a source so it is part of the registry from construction (no post-build mutation).
func (*Assembly) Dispatcher ¶
func (a *Assembly) Dispatcher() Dispatcher
Dispatcher returns the executor. Assembly itself also implements Dispatcher by delegation, so callers can take either form.
func (*Assembly) ExecuteAll ¶
ExecuteAll implements Dispatcher.
func (*Assembly) NewSession ¶
NewSession creates one per-run / per-conversation injection view. Without dynamic injection it returns a static session showing every tool.
type AssemblyFactory ¶
type AssemblyFactory struct{}
AssemblyFactory builds the standard tool assembly resource without middleware: the executor runs a bare chain. Deployments that need middleware use the tool.Assembly/middleware impl.
func (AssemblyFactory) Spec ¶
func (AssemblyFactory) Spec() resource.Spec
Spec implements resource.Factory.
type AssemblyOption ¶
type AssemblyOption func(*assemblyOptions)
AssemblyOption configures NewAssembly.
func WithConflict ¶
func WithConflict(p ConflictPolicy) AssemblyOption
WithConflict sets the duplicate-name policy for the underlying registry.
func WithDynamic ¶
func WithDynamic(p Policy) AssemblyOption
WithDynamic enables dynamic tool injection with policy p. Zero fields fall back to DefaultPolicy; tool_search is registered with ExposureAlways automatically.
func WithMiddleware ¶
func WithMiddleware(mws ...Middleware) AssemblyOption
WithMiddleware appends middleware to the executor chain, outermost first.
type AssemblySettings ¶
type AssemblySettings struct {
Dynamic *Policy `json:"dynamic,omitempty"`
}
AssemblySettings is the strict settings subtree of the memory assembly factory: the dynamic injection policy only. Middleware settings belong to the tool.Assembly/middleware impl (see core/tool/middleware); the memory impl rejects the "middlewares" key via strict decoding.
type Budget ¶
type Budget struct {
// MaxDefinitions caps the number of definitions. Zero falls back
// to DefaultBudget.MaxDefinitions.
MaxDefinitions int `json:"max_definitions,omitempty"`
// MaxBytes caps the total serialized size of the definitions. Zero
// falls back to DefaultBudget.MaxBytes.
MaxBytes int64 `json:"max_bytes,omitempty"`
}
Budget caps how many definitions reach the model per turn.
type Catalog ¶
type Catalog interface {
// Get returns the tool registered under name.
Get(name string) (Tool, bool)
// Definitions returns the Definition of every tool in the catalog.
Definitions() []message.ToolDefinition
}
Catalog is the read-side view of a tool collection: lookup plus model-facing definitions. A Registry implements it; read-side wrappers (e.g. the dynamic injection catalog) implement it over a base registry without being execution surfaces.
type ConflictPolicy ¶
type ConflictPolicy int
ConflictPolicy decides what happens when two sources contribute a tool with the same name.
const ( // ConflictError fails construction on any duplicate name. This is // the default: a silent overwrite usually means two sources // disagree about who owns a tool. ConflictError ConflictPolicy = iota // ConflictOverwrite lets a later source (in the explicit dep // order) replace an earlier tool with the same name. Use it when // a deployment intentionally overrides a base tool. ConflictOverwrite )
type Dispatch ¶
Dispatch is the function form of "execute one tool call and return its result". Middleware operates on this signature.
Implementations should treat the input call as immutable and must always return a Result — errors are reported via Result.IsError, never returned out-of-band.
type Dispatcher ¶
type Dispatcher interface {
Execute(context.Context, message.ToolCall) message.ToolResult
ExecuteAll(context.Context, []message.ToolCall) []message.ToolResult
}
Dispatcher is the execution contract consumers depend on: run one tool call, or several concurrently. *Executor is the canonical implementation, but tests and adapters may substitute their own.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor dispatches tool calls against a Catalog through a middleware chain. The un-decorated core only looks the tool up and invokes it; every cross-cutting concern — recovery, telemetry, concurrency limits, timeouts, approval, audit — is middleware, declared at construction. The chain is immutable afterwards, so an Executor is safe for concurrent use by construction.
func NewExecutor ¶
func NewExecutor(catalog Catalog, mws ...Middleware) *Executor
NewExecutor builds an Executor over catalog. Nil middleware values are skipped. catalog must be non-nil.
func (*Executor) Execute ¶
Execute runs one call through the middleware chain. All failures — unknown tool, tool error — surface as Result with IsError=true, never as a Go error.
func (*Executor) ExecuteAll ¶
ExecuteAll runs every call concurrently through the chain and returns results in input order. Concurrency is unbounded by default; put a concurrency middleware in the chain to cap it.
type Exposure ¶
type Exposure string
Exposure controls whether a tool appears in the model-visible Definitions. It is host policy, never part of message.ToolDefinition.
const ( // ExposureAlways marks a tool that appears in Definitions every // turn. Keep this set small; it is the stable baseline. ExposureAlways Exposure = "always" // ExposureDirect marks a tool that appears only when it is // RequiredByName or has been selected/used recently. ExposureDirect Exposure = "direct" // ExposureDeferred marks a tool that is hidden until tool_search // surfaces it; once selected it stays visible for M rounds. ExposureDeferred Exposure = "deferred" // ExposureHidden marks a tool that never appears in Definitions // (not even via search). RequiredByName can still surface it, and // the tool remains callable by exact name at all times. ExposureHidden Exposure = "hidden" )
type LazyTool ¶
type LazyTool struct {
Name string
Placeholder message.ToolDefinition
Load func(ctx context.Context) (Tool, error)
}
LazyTool is a deferred tool descriptor contributed by a Source. Name must equal Placeholder.Name; Load performs any network or process work the tool needs.
type Middleware ¶
Middleware wraps a Dispatch. mws[0] is outermost (sees the call first and the result last), matching agent.ComposeHost.
type Option ¶
type Option func(*options)
Option configures a Registry.
func WithConflictPolicy ¶
func WithConflictPolicy(p ConflictPolicy) Option
WithConflictPolicy sets the duplicate-name policy. The default is ConflictError; pass ConflictOverwrite to let later sources win.
type Policy ¶
type Policy struct {
// Default is the exposure applied to registered tools that have no
// explicit entry in Exposures. Empty means ExposureDeferred.
Default Exposure `json:"default,omitempty"`
// Exposures maps tool names to explicit exposure levels.
Exposures map[string]Exposure `json:"exposures,omitempty"`
// SelectedRetention is how many rounds a selected tool stays
// visible (M). Zero falls back to 5.
SelectedRetention int `json:"selected_retention,omitempty"`
// RecentWindow is how many rounds a recently used direct tool stays
// visible. Zero falls back to 10.
RecentWindow int `json:"recent_window,omitempty"`
// Budget caps the visible set. Zero uses DefaultBudget.
Budget Budget `json:"budget,omitempty"`
// SearchWithLoad makes tool_search load every deferred source
// before ranking, so hits are computed over real metadata instead
// of placeholder declarations. Default is false (lazy search).
SearchWithLoad bool `json:"search_with_load,omitempty"`
}
Policy is the host-declared injection policy for one assembly. Zero values mean "use DefaultPolicy" for every field except Exposures, so a partial settings subtree is sufficient.
func DefaultPolicy ¶
func DefaultPolicy() Policy
DefaultPolicy returns the recommended policy: everything deferred by default, 5 selected rounds, 10 recent rounds, and the default budget.
type Registrar ¶ added in v0.1.8
type Registrar interface {
// Add registers one tool. Duplicate names follow the registry's
// ConflictPolicy; adding to a closed registry returns an error.
Add(t Tool) error
// Remove unregisters the named tool, if present.
Remove(name string)
}
Registrar is the runtime mutation surface of a Registry. Sources that discover tools after construction — an MCP server that connects in the background, a refresh that re-lists remote tools — use it to publish tools as they become available.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry aggregates tools from many Source values. It implements Catalog; the underlying execution surface for an Executor is the same value. The tool set is fixed at construction — sources are a build-time concern — and changes at runtime only through the Registrar surface (Add/Remove), which deferred sources use to publish tools discovered after construction.
A Registry is safe for concurrent use. Close releases every contributed tool that implements io.Closer (deferred proxies included) and forbids further lazy loads.
func NewRegistry ¶
NewRegistry builds a registry from sources in order. With the default ConflictError policy a duplicate name is an error; with ConflictOverwrite the later source wins.
func (*Registry) Add ¶ added in v0.1.8
Add registers one tool at runtime. It follows the same duplicate policy as construction and fails after Close.
func (*Registry) Close ¶
Close releases every tool that implements io.Closer (in reverse registration order) and marks the registry closed so deferred tools can no longer load. It is idempotent.
func (*Registry) Definitions ¶
func (r *Registry) Definitions() []message.ToolDefinition
Definitions implements Catalog, sorted by name.
func (*Registry) Get ¶
Get implements Catalog. A deferred tool returns its proxy, which serves the placeholder definition until first Execute.
func (*Registry) Remove ¶ added in v0.1.8
Remove unregisters the named tool at runtime. If the removed tool implements io.Closer, it is closed so runtime removals (e.g. a shrunk MCP tool projection) release whatever resources the tool holds; the close happens outside the registry lock and is best-effort. Unknown names are ignored; after Close it is a no-op.
type RegistryAttacher ¶ added in v0.1.8
type RegistryAttacher interface {
Attach(r Registrar)
}
RegistryAttacher is an optional Source capability: the assembly hands the built Registry's Registrar to sources that need to publish tools after construction (background connects, refresh).
type RegistryFactory ¶
type RegistryFactory struct{}
RegistryFactory builds a memory registry from its many tool.Source deps. The dep order (DepsMany's sorted key order) is the explicit source order used by ConflictOverwrite.
func (RegistryFactory) Spec ¶
func (RegistryFactory) Spec() resource.Spec
Spec implements resource.Factory.
type SearchHit ¶
type SearchHit struct {
Name string `json:"name"`
Description string `json:"description"`
Score float64 `json:"score"`
}
SearchHit is one tool_search result.
type SearchTool ¶
type SearchTool struct{}
SearchTool is the model-facing discovery tool. It resolves the session from context (see WithSession) so one instance can be registered on the shared registry for all sessions.
func NewSearchTool ¶
func NewSearchTool() SearchTool
NewSearchTool returns the tool_search implementation.
func (SearchTool) Definition ¶
func (SearchTool) Definition() message.ToolDefinition
type Session ¶
type Session interface {
Catalog
// Require adds names to the RequiredByName set. Idempotent.
Require(names ...string)
// Select marks names as selected for the policy's retention
// rounds. Selection carries an implicit load contract: a selected
// tool must be loaded before the next Definitions call, otherwise
// the model would see its placeholder schema. tool_search enforces
// this by loading each name before selecting.
Select(names ...string)
// RecordCall records that the model called name this round,
// refreshing its Selected and UsedRecently state.
RecordCall(call message.ToolCall)
// AdvanceTurn moves to the next round, expiring Selected and
// UsedRecently entries. Call it once per inference round.
AdvanceTurn()
// Search ranks searchable definitions against query with BM25.
// Search never loads deferred tools.
Search(ctx context.Context, query string, limit int) ([]SearchHit, error)
// SearchWithLoad loads every deferred tool before ranking, so hits
// are computed over real metadata. It is the explicit opt-in for
// hosts that need the complete tool set; tool_search itself follows
// Policy.SearchWithLoad instead.
SearchWithLoad(ctx context.Context, query string, limit int) ([]SearchHit, error)
// Load eagerly loads every deferred tool. One failing source does
// not stop the others; errors are joined.
Load(ctx context.Context) error
// EnsureLoaded forces the deferred load of the named tools so the
// next Definitions call sees their real schemas. Unknown or
// already-concrete tools are skipped.
EnsureLoaded(ctx context.Context, names ...string) error
}
Session is the per-run / per-conversation injection view over a Catalog. An Engine creates one at run start, feeds the model Definitions() each round, records calls, and advances turns.
When the assembly was built without dynamic injection, the session is static: Definitions() shows every tool, and the stateful operations (Select/Require/RecordCall/AdvanceTurn) are no-ops while Search returns NotAvailable.
type Source ¶
Source is a multi-tool contributor to a Registry: builtin Go functions, a sandbox-backed exec set, an MCP server, a YAML document, a host-provided collection. Sources are resources in the deployment DAG; a registry aggregates them through a Many dep.
Tools() are eager — available immediately without I/O. LazyTools() are deferred: the registry stores a proxy serving LazyTool.Placeholder as its definition, and the real implementation is loaded on first Execute (never at build time).
type Tool ¶
type Tool interface {
Definition() message.ToolDefinition
Execute(ctx context.Context, arguments string) (string, error)
}
Tool is the interface that LLM-callable tools must implement.
type ToolMeta ¶
type ToolMeta struct {
// RateLimit is the maximum number of executions per second this
// tool can sustain. Zero means "no claim" (no rate limit applied).
// A negative value is treated as zero.
RateLimit float64
// MutatesState declares that this tool has side effects beyond
// returning a result (writes, posts, sends mail, ...). Zero value
// (false) is the conservative default in the opposite direction:
// callers that don't know better should assume the tool MAY mutate
// state.
MutatesState bool
// SelfTimeout declares that the tool already bounds its own
// execution time, so the timeout middleware should not impose its
// default deadline on top.
SelfTimeout bool
}
ToolMeta carries optional, execution-relevant metadata about a Tool.
All fields are advisory; a zero ToolMeta means "no claims, treat conservatively" (no rate limit, assume the tool may mutate state so retries are unsafe).
func MetadataOf ¶
MetadataOf returns the ToolMeta declared by t, or a zero ToolMeta when t does not implement ToolMetadata. Safe on nil values.
type ToolMetadata ¶
type ToolMetadata interface {
Metadata() ToolMeta
}
ToolMetadata is an optional interface a Tool may implement to declare execution-relevant metadata. Tools that do not implement it are treated as if they returned a zero ToolMeta.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package mcp attaches Model Context Protocol servers to a [tool.Registry], turning every tool a server exposes into an ordinary [tool.Tool].
|
Package mcp attaches Model Context Protocol servers to a [tool.Registry], turning every tool a server exposes into an ordinary [tool.Tool]. |
|
Package tooltest provides reusable fixtures and contract suites for core/tool implementations.
|
Package tooltest provides reusable fixtures and contract suites for core/tool implementations. |