Your first tool
@tool decorator generates the JSON schema from the Pydantic model, which the LLM uses to understand what arguments to pass.
How tool calling works
1
LLM decides to call a tool
Based on the user’s message and the tool schemas, the LLM emits a
tool_call with the function name and arguments.2
Validate arguments
AFK parses the arguments through the Pydantic model. Invalid arguments
generate a validation error that’s sent back to the LLM for self-correction.
3
Check policy gate
If a PolicyEngine is attached, the tool call is
checked against policy rules (
allow, deny, or request_approval).4
Execute the handler
The tool function runs with validated arguments. Pre/post hooks and
middleware execute around the handler.
5
Sanitize output
The output is truncated to
tool_output_max_chars, stripped of potential
prompt injection vectors (if sanitize_tool_output=True), and formatted for
the LLM.6
Return to LLM
The sanitized result is appended to the conversation and the LLM generates
its next response.
Tool patterns
- Simple return
- Structured output
- Async tool
- With context
Return a string or dict directly.
Deferred background tool calls
For long-running operations, a tool can return a deferred handle so the run can continue while work completes in the background.- Runner emits
tool_deferred. - Agent continues with other work in the same run.
- Runner emits
tool_background_resolvedortool_background_failed. - Resolved tool output is injected back into conversation for next steps.
bgtool:{run_id}:{ticket_id}:statebgtool:{run_id}:latest
Policy-gated tools
Use the PolicyEngine to gate sensitive tool calls:Hooks and middleware
AFK provides four extension points for tool execution: prehooks, posthooks, tool-level middleware, and registry-level middleware. Each has its own decorator.Prehooks — transform args before execution
Prehooks — transform args before execution
Prehooks run before the tool handler. They receive the tool’s arguments and must return a dict compatible with the tool’s
args_model.Posthooks — transform output after execution
Posthooks — transform output after execution
Posthooks run after the tool handler. They receive a dict
{"output": <tool_output>, "tool_name": "<name>"} and should return a dict with the same shape.Tool-level middleware — wrap execution
Tool-level middleware — wrap execution
Middleware wraps the entire tool execution. It receives
call_next, the validated args, and optionally ctx.Registry-level middleware — wrap all tools
Registry-level middleware — wrap all tools
Registry-level middleware applies to every tool in a
ToolRegistry. Use for audit logging, rate limiting, or global policy enforcement.Execution order
Common tools cookbook
HTTP request tool
HTTP request tool
File read tool
File read tool
Calculator tool
Calculator tool
Prebuilt tools
AFK ships with ready-to-use tools for common agent capabilities. These are in theafk.tools.prebuilts module.
Runtime tools
Filesystem tools scoped to a directory for safe agent exploration:root_dir.
Skill tools
When an agent hasskills configured, AFK generates four skill tools automatically:
Skill tools are gated by a
SkillToolPolicy that controls command allowlists, output limits, and shell operator restrictions:
Next steps
Streaming
Watch tool calls happen in real time.
Security Model
Policy gates, sandbox profiles, and tool allowlists.