Tool trait. There are three idiomatic ways to write one, each more convenient than the last when you can use it.
What a tool is
name— what the model will type to call you.description— what the model reads to decide when to call you. Make it good.args_schema— JSON Schema for the arguments. The provider sends this to the model.return_direct— whentrue, the tool’s output becomes the final response (skips the next model turn)._run— the body. ReceivesToolInput, returnsToolOutput.
When to reach for which option
Quick example — typed SchemaBasedTool
The most common shape: typed Params, derive JsonSchema, implement one method.
SchemaBasedTool provides a blanket Tool impl that handles serde, validation, and the JSON Schema for you.
Quick example — hand-written Tool
When you need control over the schema or want to handle raw ToolInput:
examples/tools/derive_tool.rs.
Wiring tools into an agent
Tools areArc<dyn Tool>. The builder accepts one or many.
ToolAllowList, ToolDenyList).
Validators
When using#[cognis::tool] or SchemaBasedTool, you can declare per-field validators that emit both runtime checks and JSON Schema constraints:
These ride on the args struct fields — the model sees them in the schema, and your tool receives validated input.
Built-in tools
Cognis ships a few generally useful tools undercognis::tools::*:
Calculator— pure-Rust expression evaluator (+ - * / % ^, parens, unary-). No code execution.FilesystemToolfamily — read/write/edit/list a workspace, gated by aBackend.HttpRequest(featuretools-http) — make HTTP calls with allow-listed hosts.JsonQuery— JMESPath-like query over JSON.PythonRepl— sandboxed Python execution (where the runtime is available).OpenApiTool— generate tools from an OpenAPI spec.HumanTool— ask a human a question, return their reply.
ToolOrchestrator (no-loop DAG)
When you need to call a fixed set of tools in a known DAG — not an agent loop — useToolOrchestrator:
How it works
- The model never sees Rust types directly. It sees the JSON Schema you produce. Make descriptions and field docs clear — that’s the model’s only signal.
- Tool dispatch is a node in the agent graph. When the model emits tool calls, the dispatcher node parses arguments, runs the tool, and threads the result back as a
Message::toolentry tied to the call id. - Errors are tool-shaped. Returning an error from
_runbecomes aToolMessagewith the error text — the agent sees it and can recover or apologize.
See also
Models and providers
The other half of the agent — the LLM that picks the tool.
Human-in-the-loop
Require approval before sensitive tools run.
Middleware
ToolAllowList, ToolDenyList, ToolRetry, ToolEmulator.Patterns → HITL approval
A worked tool-approval flow.