feat: conversion-driven extensions — resolvers, DefineTool, hooks, ops controls
CI / Tidy (push) Successful in 9m31s
CI / Build & Test (push) Successful in 10m13s

Phase 9a (ADR-0014): Registry.RegisterResolver for dynamic tiers;
DefineTool[Args] typed tools; Usage cache/reasoning detail fields wired
through anthropic/openai/google; WithPromptCaching (Anthropic
cache_control); agent supervision hooks (WithMaxStepsFunc, WithSteer,
WithCompactor, WithToolErrorLimits + ErrToolLoop); health
Bench/Unbench/Snapshot; ChainConfig.Observer failover events.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 13:30:06 +02:00
parent 04b21fdad2
commit 0147a79d18
21 changed files with 767 additions and 29 deletions
+34
View File
@@ -22,6 +22,40 @@ type Tool struct {
Handler func(ctx context.Context, args json.RawMessage) (any, error)
}
// DefineTool builds a typed tool: the parameter schema is derived from
// Args (see SchemaFor) and the raw JSON arguments are unmarshaled into an
// Args value before the handler runs.
//
// weather := llm.DefineTool("get_weather", "Current weather for a city",
// func(ctx context.Context, args struct {
// City string `json:"city" description:"city name"`
// }) (any, error) {
// return lookup(args.City)
// })
//
// Schema derivation failures panic: tools are defined at startup and an
// unschematizable Args type is a programming error worth failing loudly on.
func DefineTool[Args any](name, description string, fn func(ctx context.Context, args Args) (any, error)) Tool {
schema, err := SchemaFor[Args]()
if err != nil {
panic(fmt.Sprintf("llm: DefineTool(%q): %v", name, err))
}
return Tool{
Name: name,
Description: description,
Parameters: schema,
Handler: func(ctx context.Context, raw json.RawMessage) (any, error) {
var args Args
if len(raw) > 0 {
if err := json.Unmarshal(raw, &args); err != nil {
return nil, fmt.Errorf("invalid arguments for %s: %w", name, err)
}
}
return fn(ctx, args)
},
}
}
// ToolCall is a model's request to invoke a tool.
type ToolCall struct {
// ID is the provider-assigned call id; majordomo synthesizes one for