Built-in tools
| Tool | Package | Description |
|---|---|---|
| Calculator | pkg/tools/calculator | Safe AST-based math evaluation |
| WebSearch | pkg/tools/websearch | Pluggable search backend |
Custom tools
TypedFunc — one-line tool definition
Usetools.TypedFunc[TInput] to define a tool from a typed struct. Schema generation, JSON marshalling, and unmarshalling are handled automatically — no boilerplate required.
MustTypedFunc in package-level declarations or test setup:
Func — raw JSON handler
For full control over input parsing, usetools.Func directly:
Schema shorthand methods
TheSchema builder now has typed shorthand methods so you don’t need to construct Property literals manually:
| Method | JSON schema type |
|---|---|
AddString(name, desc, required) | "string" |
AddInt(name, desc, required) | "integer" |
AddNumber(name, desc, required) | "number" |
AddBool(name, desc, required) | "boolean" |
Struct-based schema
Generate a JSON schema directly from a Go struct using field tags — noNewSchema() calls needed:
| Tag | Effect |
|---|---|
json:"fieldName" | Property name (falls back to Go field name) |
cf:"required" | Marks the field as required |
cf:"description=My desc" | Sets the property description |
cf:"enum=a|b|c" | Restricts to listed values |
cf directives can be combined: cf:"required,description=The query,enum=json|text".
Go type → JSON schema type:
| Go type | Schema type |
|---|---|
string | "string" |
int, int8…int64, uint… | "integer" |
float32, float64 | "number" |
bool | "boolean" |
[]T, [N]T | "array" |
| everything else | "object" |
Parsing tool input
Inside a tool handler, usetools.ParseInput[T] to unmarshal the JSON input string into a typed struct:
ParseInput returns a tools: invalid input: ... error on malformed JSON.
Cached tools
Wrap any tool withCachedTool to memoize results by input JSON string. Useful for expensive or rate-limited tools that may be called repeatedly with the same arguments.
- Results (including errors) are stored by exact input JSON string.
- Concurrent calls with the same input call the inner tool exactly once — subsequent calls return the cached value.
- Call
cached.InvalidateAll()to flush the cache on demand.
CachedTool delegates Definition() to the wrapped tool, so the LLM sees the same schema.
TTL-based expiry
UseNewCachedToolWithTTL to automatically expire cache entries after a duration:
NewCachedTool — entries never expire. Cache expiry uses a sliding window: the timestamp is recorded on first call; the next call after TTL elapses re-invokes the inner tool and refreshes the entry.
Tool errors
Tool execution errors are non-fatal. The error string is returned to the LLM as the tool result so the model can observe and handle it — the agent loop continues.RetrieverTool — LLM-driven RAG
Wrap anyrag.Retriever as a core.Tool so the LLM can call retrieval explicitly:
retriever_tool with {"query": "..."} to fetch relevant context on demand. For automatic injection on every turn, use chainforge.WithRetriever instead. See the RAG guide.