tool

package module
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package tool provides the loop.Handler bridge, concrete tool implementations, and tool discovery mechanisms for ore.

Note: this is the x/tool extension package; it is typically imported as xtool (e.g. xtool "github.com/andrewhowdencom/ore/x/tool") to differentiate from the core tool package that defines the contracts.

The core tool execution contracts (Registry interface, ToolFunc, RemoteSource, and ValidateSchema) live in the root tool/ package. This extension package bridges those contracts to the loop framework via Handler, and provides concrete tool implementations (bash, calculator, filesystem), MCP client integration, and skills discovery.

A Handler implements loop.Handler. It detects artifact.ToolCall artifacts, looks up the tool by name in its registry (local or remote), executes the corresponding function, and emits a TurnCompleteEvent with RoleTool and a ToolResult artifact. Using Emit keeps tool results on the same observable event stream as other artifacts, allowing UI conduits to render them without special-casing. Unknown tools are refused with an error result.

Tool calling composes three mechanisms:

  1. Root tool/ package — provides the Registry interface, ToolFunc contract, RemoteSource abstraction, and schema validation. This is the core framework primitive.

  2. Provider adapter (e.g., x/provider/openai/) — accepts tool configuration per-invocation via openai.WithTools(), serializes them in requests, deserializes ToolCall from responses, and serializes RoleTool turns with ToolResult back to the provider.

  3. Artifact Handler (this package) — bridges the root tool/ Registry to the loop framework via NewHandler(), which implements loop.Handler.

The application wires them together:

import (
    "github.com/andrewhowdencom/ore/tool"
    xtool "github.com/andrewhowdencom/ore/x/tool"
)

registry := tool.NewRegistry()
if err := registry.Register(tool.Tool{Name: "add", Description: "Add two numbers", Schema: schema}, func(ctx context.Context, _ tool.Sandbox, args map[string]any) (any, error) {
    a, _ := args["a"].(float64)
    b, _ := args["b"].(float64)
    return a + b, nil
}); err != nil {
    ...
}

prov, err := openai.New(openai.WithAPIKey(apiKey), openai.WithModel(model))
if err != nil { ... }

// Registry.Tools() is the single source of truth.
step := loop.New(
    loop.WithHandlers(xtool.NewHandler(registry)),
    loop.WithInvokeOptions(openai.WithTools(registry.Tools())),
)

MCP servers can be composed into the same registry via the root tool package:

mcpClient, err := mcp.NewClient(mcp.WithName("filesystem"), mcp.WithStdio("python", "server.py"))
if err != nil { ... }

registry := tool.NewRegistry(tool.WithMCPServer(mcpClient))

Dynamic tool configuration. The tool list can be evolved during a session by passing different provider-level InvokeOption values (e.g. openai.WithTools or WithFilteredTools) to each Step.Turn call. This allows the application to prune, expand, or replace tools based on context, user permissions, or discovered capabilities:

// Pass different tool sets per-turn.
tools := selectToolsForContext(ctx, state)
_, err := step.Turn(ctx, state, prov, openai.WithTools(tools))

The x/tool package also provides a convenience constructor for the common dynamic-filtering pattern. Instead of manually selecting tools per-turn, applications can register a filter function that is called automatically on each invocation:

import (
    "context"
    "github.com/andrewhowdencom/ore/provider"
    "github.com/andrewhowdencom/ore/ledger"
    "github.com/andrewhowdencom/ore/x/provider/openai"
    xtool "github.com/andrewhowdencom/ore/x/tool"
)

filter := func(ctx context.Context, st ledger.State, tools []tool.Tool) []tool.Tool {
    // Return only tools permitted for the current user/role.
    return filterByRole(tools, st)
}
opt := xtool.WithFilteredTools(registry, filter)
_, err := step.Turn(ctx, state, prov, opt)

A nil filter is treated as an identity function — it returns the full slice of tools obtained from the registry unchanged.

Because tools are passed per-invocation through provider.InvokeOption, there is no mutable provider state and no need for synchronization. The tool.Tool struct is provider-agnostic — each adapter maps it to its native API.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithFilteredTools added in v0.3.2

func WithFilteredTools(registry toolpkg.Registry, filter ToolFilter) provider.InvokeOption

WithFilteredTools returns a provider.InvokeOption that resolves tools from the given registry and applies the filter function before passing them to the provider. If filter is nil, all tools from the registry are returned unmodified.

Types

type Handler

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

Handler implements loop.Handler for executing tool calls. It looks up the tool by name in its registry, parses JSON arguments, executes the function, applies the tool's Format (truncation, recovery hint) to the result, and emits a TurnCompleteEvent with RoleTool and a ToolResult artifact.

func NewHandler

func NewHandler(registry toolpkg.Registry, opts ...HandlerOption) *Handler

NewHandler creates a Handler backed by the given registry.

func (*Handler) Handle

func (h *Handler) Handle(ctx context.Context, art artifact.Artifact, e loop.Emitter) error

Handle processes a single artifact. If the artifact is not a ToolCall, it is ignored. For ToolCall artifacts, the handler looks up the tool in the registry, executes it, applies the tool's Format, and emits a TurnCompleteEvent with RoleTool and a ToolResult artifact.

type HandlerOption added in v0.4.2

type HandlerOption func(*Handler)

HandlerOption configures a Handler.

func WithTracer added in v0.4.2

func WithTracer(tracer trace.Tracer) HandlerOption

WithTracer configures an OpenTelemetry tracer for the handler.

type ToolFilter added in v0.3.2

type ToolFilter func(ctx context.Context, st ledger.State, tools []toolpkg.Tool) []toolpkg.Tool

ToolFilter is a function that selects a subset of tools based on runtime context and ledger. It receives the full tool list from a registry and returns the subset that should be presented to the provider for the current turn.

Directories

Path Synopsis
bash module
calculator module
filesystem module
sandbox
unsafe module
set_model module
set_title module
settitle module
skills module
truncate module

Jump to

Keyboard shortcuts

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