Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add agents/evalstate/fast-agent/tool_runnergit clone --depth 1 https://github.com/evalstate/fast-agentWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.00848 |
| Opus 5 | $0.00000 | $0.00424 |
| Sonnet 5 | $0.00000 | $0.00170 |
| Haiku 4.5 | $0.00000 | $0.00085 |
Grade A, and why
tool_runner scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 106 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Tool Runner
Tool Runner is the internal loop that powers tool calling for ToolAgent and MCP agents. It:
- Sends messages to the LLM.
- Detects tool requests.
- Executes tools.
- Feeds tool results back into the loop until the assistant is done.
Hooks (optional)
You can attach lightweight hooks to the Tool Runner without changing the core agent protocol.
Implement the ToolRunnerHookCapable capability and expose a tool_runner_hooks property.
Available hook points:
before_llm_callafter_llm_callbefore_tool_callafter_tool_callafter_turn_complete
after_llm_call runs after every assistant response from the model, including
intermediate responses that request tools. before_tool_call and
after_tool_call wrap each tool-execution step. after_turn_complete runs once
at the end of the whole user turn, after any model/tool/model loop has finished,
and receives the final message for that turn.
Built-in hooks
fast-agent ships several after_turn_complete hooks built on this mechanism,
applied automatically and gated by config:
- Auto-compaction — summarizes older history when context usage crosses
compaction.threshold. See Compaction. - History trimming —
trim_tool_history: trueon an agent collapses a multi-call tool loop to its last call, result, and final response. - Session-history persistence — saves the conversation after each turn when
session_historyis enabled.
These coexist with any hooks you attach: built-ins run in a fixed order
(custom/trim → compact → session save) so a custom after_turn_complete hook
still fires.
Minimal example
import asyncio
from fast_agent import FastAgent
from fast_agent.agents.agent_types import AgentConfig
from fast_agent.agents.tool_agent import ToolAgent
from fast_agent.agents.tool_runner import ToolRunnerHooks
from fast_agent.context import Context
from fast_agent.interfaces import ToolRunnerHookCapable
from fast_agent.types import PromptMessageExtended
def get_video_call_transcript(video_id: str) -> str:
return "Assistant: Hi, how can I assist you today?\n\nCustomer: Hi, I wanted to ask you about last invoice I received..."
class HookedToolAgent(ToolAgent, ToolRunnerHookCapable):
def __init__(self, config: AgentConfig, context: Context | None = None):
super().__init__(config, [get_video_call_transcript], context)
self._hooks = ToolRunnerHooks(
before_llm_call=self._add_style_hint,
after_tool_call=self._log_tool_result,
)
@property
def tool_runner_hooks(self) -> ToolRunnerHooks | None:
return self._hooks
async def _add_style_hint(self, runner, messages: list[PromptMessageExtended]) -> None:
if runner.iteration == 0:
runner.append_messages("Keep the answer to one short sentence.")
async def _log_tool_result(self, runner, message: PromptMessageExtended) -> None:
if message.tool_results:
tool_names = ", ".join(message.tool_results.keys())
print(f"[hook] tool results received: {tool_names}")
fast = FastAgent("Example Tool Use Application (Hooks)")
@fast.custom(HookedToolAgent)
async def main() -> None:
async with fast.run() as agent:
await agent.default.generate("What is the topic of the video call no.1234?")
if __name__ == "__main__":
asyncio.run(main())
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday First seen · 106 lines · 0 tokens per session scan A f3fb1087f977
tool_runner is an agent published in the GitHub repository evalstate/fast-agent (3,904 stars, last pushed 2d ago), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 848 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other agents, from other repositories
agentlas-core-engine-meta-agent
Use this agent when the user asks for /meta-agent, a single agent builder, multi-agent team builder, or packaging existing agents into Agentlas architecture.
Explore
Fast read-only codebase & docs exploration. Returns structured findings, never raw file dumps.
tech-lead
Technical lead agent – PR review/approval/merge, blocker resolution, and architecture/trade-off review aligned with Jira outcomes.
unittest-generator
Use this agent when you need to create unit tests for your code in unittest.TestCase format, organized in a tests folder with concept-based subfolders. Examples: Context: User has just written a new authentication module and needs comprehensive unit tests. user: 'I just finished writing my user authentication…
external-system-integration-expert
你负责把当前项目与外部 API、API 网关及业务系统安全地连接起来:识别集成边界、整理接口与环境差异、验证请求和响应、定位认证或数据契约问题。.
DocScribe
Write docs/ prose for a completed change, in caveman style, per the repo's Documentation Update Protocol. Use after a change lands to update docs/architecture.md, docs/ .md, README, or docs/AGENTS.md — the Rule-6 delegation target (main agent must NOT edit docs/ directly). Self-contained — give it the diff + target…