Tools are how an agent reaches outside the chat — searching the web, querying a database, running calculations, calling your domain functions. In Cognis, every tool implements theDocumentation Index
Fetch the complete documentation index at: https://cognis.vasanth.xyz/llms.txt
Use this file to discover all available pages before exploring further.
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
| You have… | Use |
|---|---|
| A simple async function with typed inputs | #[cognis::tool] macro |
| A struct with config (HTTP client, DB pool) and a typed input | SchemaBasedTool trait |
| Anything more custom | Hand-written impl Tool |
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:
| Attribute | Effect |
|---|---|
#[schema(range(min = 0, max = 100))] | Numeric bounds. |
#[schema(length(min = 1, max = 200))] | String / Vec length. |
#[schema(pattern("^[A-Z][a-z]+$"))] | Regex. |
#[schema(enum_values("low", "medium", "high"))] | Enum. |
#[schema(format("email"))] | JSON Schema format. |
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.