tool

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package tool implements the Tool Gateway decision chain of the Fenced kernel: versioned descriptors, canonical argument normalization, policy evaluation, human approval binding, budget hard-stop and durable side-effect receipts (architecture §9.2, §12.2; invariants 6 and 9).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrToolArgsInvalid reports arguments that fail schema validation or
	// size bounds.
	ErrToolArgsInvalid = errors.New("tool arguments are invalid")
	// ErrBudgetExhausted is the hard-stop outcome: the task budget is
	// exhausted and new consumption must stop (invariant 12).
	ErrBudgetExhausted = errors.New("task budget exhausted: new consumption stopped")
	// ErrToolExecutionFailed reports a tool that ran but did not succeed; the
	// failure is already recorded in the side-effect receipt.
	ErrToolExecutionFailed = errors.New("tool execution failed")
)

Functions

func CompareToolVersions

func CompareToolVersions(left, right string) int

CompareToolVersions orders two tool versions: semantic versions compare numerically; anything else falls back to a byte-wise comparison so non-semver registry labels stay deterministic.

func LatestVersionPerName

func LatestVersionPerName(descriptors []store.ToolDescriptor) []store.ToolDescriptor

LatestVersionPerName collapses descriptors to exactly one entry per tool name: the latest version among the given (already capability-filtered) set, in stable name order (P1-02). The model-facing surface must never advertise two same-named tools — duplicate names are ambiguous for the model and rejected by downstream consumers — while invocation keeps resolving bare names to this same latest version, so what tools/list shows is exactly what a bare-name call executes. Explicit "name@version" references continue to pin any granted older version.

func NormalizeArgs

func NormalizeArgs(paramsSchema json.RawMessage, args []byte, maxBytes int64) (json.RawMessage, [sha256.Size]byte, error)

NormalizeArgs validates the invocation arguments against the descriptor's JSON Schema, rejects non-object or oversized documents, and returns the canonical normalized document together with its SHA-256. Two invocations with semantically identical arguments always hash to the same value, which is what approvals and idempotency are bound to; the normalized document is what the executing adapter receives.

Types

type ApprovalNotUsableError

type ApprovalNotUsableError struct {
	Reason ApprovalNotUsableReason
	Err    error
}

ApprovalNotUsableError carries the reason behind an unusable approval.

func (*ApprovalNotUsableError) Error

func (e *ApprovalNotUsableError) Error() string

func (*ApprovalNotUsableError) Unwrap

func (e *ApprovalNotUsableError) Unwrap() error

type ApprovalNotUsableReason

type ApprovalNotUsableReason string

ApprovalNotUsableReason classifies why a bound approval cannot authorize an invocation, so the fenced boundary and the runtime can react differently to "still pending" (park) versus "rejected or expired" (fail).

const (
	ApprovalPending         ApprovalNotUsableReason = "PENDING"
	ApprovalRejected        ApprovalNotUsableReason = "REJECTED"
	ApprovalExpired         ApprovalNotUsableReason = "EXPIRED"
	ApprovalBindingMismatch ApprovalNotUsableReason = "BINDING_MISMATCH"
)

type ExecutionRequest

type ExecutionRequest struct {
	Descriptor store.ToolDescriptor
	Action     string
	Resource   string
	Args       json.RawMessage
	Secret     SecretHandle
}

ExecutionRequest is the sanitized input an executing adapter receives.

type ExecutionResult

type ExecutionResult struct {
	Output      json.RawMessage
	FailureCode string
}

ExecutionResult is the outcome of one tool execution. Output must already be sanitized by the adapter; the gateway additionally bounds and redacts it.

type Gateway

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

Gateway orchestrates the tool decision chain. It is the enforcement point for policy, approval binding, budget hard-stop and receipts; the executing adapter is injected so the chain is testable without real tools.

func NewGateway

func NewGateway(policyChecker PolicyChecker, tools store.ToolStore, budget store.BudgetStore,
	receipts ReceiptStore, executor ToolExecutor, secrets SecretBroker, options ...GatewayOption) *Gateway

func (*Gateway) GetToolDescriptor

func (g *Gateway) GetToolDescriptor(ctx context.Context, tenantID, name, version string) (store.ToolDescriptor, error)

GetToolDescriptor returns one immutable descriptor. An empty version selects the registry's latest; the gateway service pins a concrete version before it reaches here whenever a capability freeze is enforced.

func (*Gateway) InvokeTool

func (g *Gateway) InvokeTool(ctx context.Context, in InvokeInput) (InvokeResult, error)

InvokeTool runs one invocation through the full decision chain.

func (*Gateway) ListTools

func (g *Gateway) ListTools(ctx context.Context, tenantID string) ([]store.ToolDescriptor, error)

ListTools returns the tenant's registered tool descriptors.

type GatewayOption

type GatewayOption func(*Gateway)

GatewayOption configures a Gateway.

func WithApprovalTTL

func WithApprovalTTL(ttl time.Duration) GatewayOption

WithApprovalTTL sets the lifetime of created approval requests (default 15 minutes).

func WithBounds

func WithBounds(maxArgsBytes, maxResultBytes int64) GatewayOption

WithBounds sets the argument and result size bounds (defaults 64 KiB and 1 MiB).

func WithClock

func WithClock(now func() time.Time, newID func() uuid.UUID) GatewayOption

WithClock overrides the clock and ID source for tests.

type InvokeInput

type InvokeInput struct {
	TenantID  string
	TaskID    uuid.UUID
	RunID     uuid.UUID
	AttemptID uuid.UUID
	// FencingToken is the fenced identity of the invoking Attempt. The
	// gateway itself does not verify it (lease/fencing is enforced by the
	// Runtime Protocol boundary); carriers pass it through so downstream
	// fenced transports (for example a worker's gRPC forwarding) can
	// preserve it.
	FencingToken    int64
	AgentVersionRef string
	// SecretRef is an optional symbolic capability from the immutable
	// AgentVersion manifest. Empty means this invocation receives no secret.
	SecretRef string
	ToolName  string
	// ToolVersion selects a descriptor; empty resolves the latest version.
	ToolVersion    string
	Action         string
	Resource       string
	Args           json.RawMessage
	IdempotencyKey string
	// ApprovalID is required when the previous decision was REQUIRES_APPROVAL
	// and a human decided it; the gateway re-checks the binding (§9.2).
	ApprovalID *uuid.UUID
}

InvokeInput is a fenced tool invocation from a running Attempt.

type InvokeOutcome

type InvokeOutcome string

InvokeOutcome classifies the result of an invocation.

const (
	// OutcomeExecuted: the tool ran and its receipt is durable.
	OutcomeExecuted InvokeOutcome = "EXECUTED"
	// OutcomeDenied: policy denied the invocation; nothing ran.
	OutcomeDenied InvokeOutcome = "DENIED"
	// OutcomeRequiresApproval: a human decision is required; no budget or
	// side effect was touched.
	OutcomeRequiresApproval InvokeOutcome = "REQUIRES_APPROVAL"
	// OutcomeReplayed: the identical invocation already ran; the stored
	// receipt is returned without re-execution.
	OutcomeReplayed InvokeOutcome = "REPLAYED"
)

type InvokeResult

type InvokeResult struct {
	Outcome          InvokeOutcome
	ToolCall         store.ToolCall
	ApprovalID       *uuid.UUID
	Result           json.RawMessage
	ReceiptOperation string
	DenyReasons      []string
	PolicyRevision   string
}

InvokeResult is the machine-readable outcome of an invocation.

type PolicyChecker

type PolicyChecker interface {
	EvaluateTool(context.Context, string, policy.ToolContext) policy.Decision
}

PolicyChecker decides tool invocations outside the LLM. The engine is fail-closed: missing tenant data and evaluation errors deny by default.

type ReceiptStore

type ReceiptStore interface {
	GetRuntimeReceipt(context.Context, string, uuid.UUID, string, string) (store.RuntimeReceipt, error)
	WriteRuntimeReceipt(context.Context, store.WriteRuntimeReceiptInput) error
}

ReceiptStore persists and replays side-effect receipts (at-least-once + idempotent consumer contract, ADR-003).

type SecretBroker

type SecretBroker interface {
	Issue(context.Context, SecretScope) (SecretHandle, error)
}

SecretBroker issues scoped handles for a tool invocation.

type SecretHandle

type SecretHandle string

SecretHandle is an opaque, scope-limited capability handle. The actual credential is injected by the Tool Gateway into the executing adapter and never reaches the Agent (architecture §12.4).

type SecretScope

type SecretScope struct {
	TenantID  string
	AttemptID string
	ToolName  string
	Resource  string
	SecretRef string
}

SecretScope describes the constrained capability a tool may use.

type ToolExecutionError

type ToolExecutionError struct {
	Code string
	Err  error
}

ToolExecutionError carries the machine-readable failure code of a tool that ran but did not succeed. The receipt already records the failure, so a replay returns the same outcome.

func (*ToolExecutionError) Error

func (e *ToolExecutionError) Error() string

func (*ToolExecutionError) Unwrap

func (e *ToolExecutionError) Unwrap() error

type ToolExecutor

type ToolExecutor interface {
	Execute(context.Context, ExecutionRequest) (ExecutionResult, error)
}

ToolExecutor runs one tool invocation with a constrained credential.

Jump to

Keyboard shortcuts

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