Built-in Tool Reference
LibreFang ships with a wide built-in tool catalog beyond the file / shell / web tools that show up in standard agent templates. This page covers the families that historically lived only in source code — browser automation, subprocess lifecycle, runtime scheduling, knowledge graphs, media, and inter-agent messaging.
Per-agent capability grants control which families an agent can actually call. Use agent.toml [capabilities] (or the librefang agent grant CLI) to opt agents into the tool families below.
Meta-Tools (Lazy Loading)
Two meta-tools let an agent discover and load tools on demand instead of carrying the full schema in every prompt.
| Tool | Purpose |
|---|---|
tool_search(query) | Returns tools matching query (name, description, tag). Cheap to call — no side effects. |
tool_load(name) | Pulls a tool's full schema into the active session. Subsequent turns can call it. |
Lazy loading is opt-in per agent via lazy_tools = true in the manifest. Disable to restore the legacy "all tools always loaded" behaviour. This is what the Lazy Tool Loading mention on Agent Templates refers to.
Inter-Agent Messaging (A2A)
Agents in different LibreFang instances can discover and message each other over the A2A protocol.
| Tool | Arguments | Purpose |
|---|---|---|
a2a_discover | url | Probe a remote A2A endpoint, return the agent card (/.well-known/agent.json). |
a2a_send | agent_id, message, optional task_id | Send a task to a remote A2A agent and wait for the reply. |
a2a_send is synchronous from the calling agent's perspective — it blocks until the remote turn completes (or the task TTL expires). For fire-and-forget delivery, use notify_owner or a webhook target instead.
Same-Daemon Inter-Agent Tools
For talking to other agents inside the same LibreFang daemon (no A2A protocol overhead) — spawn, list, find, kill, and send messages directly.
| Tool | Arguments | Purpose |
|---|---|---|
agent_send | agent_id, message | Send a message to another agent in this daemon and wait for the reply. Uses the in-process kernel router; respects the agent_call depth limit. |
agent_spawn | template, optional name, goal | Spawn a child agent from a template. Returns the new agent_id. Sub-agents are denied agent_spawn and agent_kill by default to prevent fork bombs. |
agent_list | — | List accessible agents (id, name, status). |
agent_find | query | Search agents by name, ID, or tag. |
agent_kill | agent_id | Terminate a running agent. Forbidden in sub-agent context by default. |
goal_update | goal | Update this agent's goal/objective mid-turn. The new goal is written into the agent's manifest and surfaces in subsequent prompts. |
max_agent_call_depth in [kernel] (default 5) caps how deep an agent_send chain can recurse — prevents A→B→A loops from ever reaching production.
Memory Tools (per-agent)
Direct access to the agent's proactive-memory store from inside the loop. Distinct from the auto-recall machinery — these are the tools the agent can call explicitly.
| Tool | Arguments | Purpose |
|---|---|---|
memory_store | content, optional category, scope | Persist a custom memory entry. scope ∈ user_memory / session_memory / agent_memory. |
memory_recall | query, optional limit, scope | Semantic search over the agent's memories. |
memory_list | optional category, scope, limit | Enumerate memories without a search query. |
See Memory System for the entry schema, scopes, decay formula, and consolidation trigger.
Task Queue Tools
The shared task board lets agents post work that other agents can claim. Useful for fan-out, oncall handoff, and long-running async jobs.
| Tool | Arguments | Purpose |
|---|---|---|
task_post | title, body, optional assignee, priority | Create a new task in the shared queue. |
task_claim | optional priority_filter | Claim ownership of the highest-priority pending task. The TTL is [task_board] claim_ttl_secs (default 600s). |
task_complete | task_id, optional result | Mark a claimed task done. |
task_list | optional status, assignee | List tasks with optional filters. |
task_status | task_id | Look up one task by ID and return its status, result, title, assigned_to, created_at, completed_at. Native counterpart of the comms_task_status MCP bridge tool — agents that delegated work via task_post can poll the outcome without loading the bridge. |
The claim TTL exists to recover from worker crashes — if the claimer doesn't task_complete within the TTL, the sweeper resets the task to pending so another worker can pick it up.
Channel Tools
| Tool | Arguments | Purpose |
|---|---|---|
channel_send | channel, target, content (text / image / file / poll) | Send a message, image, file, or poll to a channel user — without going through the agent loop. Useful for pushing alerts, async results, or out-of-band notifications. |
channel_send is what [deliver_only] webhook mode uses internally; agents can also call it directly. Capability: channel.*.
Workflow / Event Tools
| Tool | Arguments | Purpose |
|---|---|---|
workflow_run | workflow_id, optional inputs | Execute a stored workflow synchronously and return its result. |
event_publish | event_type, payload | Publish a structured event onto the event bus. Triggers ([[trigger]] blocks on agent manifests) listening on event_type will fire. |
system_time | — | Get the daemon's current wall-clock time (RFC3339 UTC). Cheap; no external clock call. |
event_publish is the bridge between agents and the trigger system — an agent that detects "a new file landed in /inbox" can publish inbox.new_file, and any trigger configured on that event runs.
Skill Evolution (extended)
In addition to skill_evolve_patch (documented above with its 5-strategy fuzzy matcher) and skill_read_file:
| Tool | Arguments | Purpose |
|---|---|---|
skill_evolve_create | name, manifest, optional body | Create a brand-new skill from scratch. |
skill_evolve_update | name, body | Replace a skill's body wholesale (no fuzzy match — just overwrite). |
skill_evolve_delete | name | Delete a skill entirely. |
skill_evolve_rollback | name, optional version | Revert a skill to a prior version. Without version, rolls back one step. |
skill_evolve_write_file | skill, path, body | Add a supporting file under references/ / templates/ / scripts/ / assets/. |
skill_evolve_remove_file | skill, path | Remove a supporting file. |
Every skill_evolve_* operation appends to the skill's evolution history; GET /api/skills/{name} returns the full audit trail.
Browser Automation
Eight tools wrap a Playwright-controlled headless browser. All of them require the agent to have the browser.* capability and a configured [browser] section in config.toml (see Core Configuration).
| Tool | Purpose |
|---|---|
browser_navigate(url) | Open or navigate the active tab. |
browser_back() | Navigate back one step in the tab's history stack. |
browser_click(selector) | Click the element matching the CSS / text selector. |
browser_type(selector, text) | Focus the element and type text (key-by-key, debounced). |
browser_scroll(direction, amount?) | Scroll up / down / to selector. |
browser_wait(condition, timeout_ms?) | Wait for selector / network-idle / time. |
browser_screenshot(full_page?) | Capture the viewport (or full page) as a ContentBlock::ImageFile. |
browser_read_page() | Extract the page's full text + structural outline (cheaper than a screenshot when the model just needs text). |
browser_run_js(script) | Run arbitrary JS in the page context, return the JSON-serialised result. |
browser_close() | Close the active tab and release the slot. |
Pages opened by an agent are scoped to that agent's tab pool (default 4). When the pool is full, browser_navigate rejects with ToolError::ResourceExhausted rather than silently evicting another tab.
Process Lifecycle
Five tools manage long-running subprocesses (build watches, test loops, log tailers, sidecar daemons). They expose stdin / stdout / stderr as a stream the agent can poll.
| Tool | Purpose |
|---|---|
process_start(command, cwd?, env?) | Spawn a subprocess. Returns a process_id. |
process_write(process_id, data) | Write bytes to the subprocess's stdin. |
process_list() | List active processes for this agent (id, cmd, age, pid). |
process_poll(process_id, max_bytes?) | Read up to max_bytes of new output since the last poll. Non-blocking. |
process_kill(process_id, signal?) | Send a signal (default SIGTERM); the runtime escalates to SIGKILL after the grace period. |
Subprocesses inherit the agent's workspace as cwd by default, the agent's environment minus other providers' secrets, and are stopped on agent shutdown. Total wall-clock budget is enforced via the [exec_policy] section.
Runtime Scheduling
Manifest [[cron]] entries are the static way to schedule turns. These tools let an agent dynamically create / list / cancel scheduled work from the loop itself.
| Tool | Purpose |
|---|---|
schedule_create(when, prompt, channel?) | Schedule a single future turn at a one-shot timestamp. |
schedule_list() | List the agent's scheduled turns. |
schedule_delete(schedule_id) | Cancel a scheduled turn. |
cron_create(expression, prompt, channel?) | Schedule a recurring turn (5-field cron). |
cron_list() | List the agent's runtime-created cron jobs. |
cron_cancel(cron_id) | Cancel a runtime cron job. |
Runtime jobs created with these tools are persisted in the same store as manifest crons — they survive daemon restarts. Their cron_id / schedule_id is opaque; round-trip through cron_list() to discover it.
Knowledge Graph
The agent-private knowledge graph stores entities and typed relations between them. Use it for structured recall ("which projects use which library") that's awkward to express as flat memory entries.
| Tool | Purpose |
|---|---|
knowledge_add_entity(name, type, attributes?) | Insert or update an entity. |
knowledge_add_relation(from, to, type, weight?) | Add a directed relation between two entities. |
knowledge_query(start, depth?, relation_filter?) | BFS from start, return reachable nodes + edges. |
The graph is per-agent and persisted in SQLite alongside the agent's session history. Use the proactive-memory tools for unstructured recall.
Media Generation & Analysis
Tool calls into provider-specific media APIs. Per-tool capability grants required.
| Tool | Purpose |
|---|---|
image_generate(prompt, size?, style?) | Generate an image (OpenAI / Replicate / Vertex). |
image_analyze(image, question) | Vision Q&A on an existing image. |
media_describe(image_or_video) | Caption / describe an existing media asset. |
media_transcribe(audio) | Speech-to-text on an audio file. |
speech_to_text(audio) | Alias of media_transcribe. |
text_to_speech(text, voice?) | TTS synthesis. |
music_generate(prompt, lyrics?) | Music generation (Suno / Replicate). |
video_generate(prompt, duration_secs?) | Submit a video-generation task; returns task_id. |
video_status(task_id) | Poll a video task. |
canvas_present(html) | Render an interactive HTML canvas in the dashboard. |
Cost and latency vary widely between providers — check [media] providers in config.toml to control which provider serves each tool.
Owner Notifications
| Tool | Purpose |
|---|---|
notify_owner(reason, summary, urgency?) | Send a private notice to the agent's owner without posting to chat. |
notify_owner writes to the owner's inbox and optionally fans out to a configured side channel (Telegram, email). Distinct from a regular reply — the message stays out of the active chat history, so it won't pollute downstream summarisation. See ReplyEnvelope.owner_notice in the API reference for the wire shape.
Geolocation, Docker, Skills
| Tool | Purpose |
|---|---|
location_get() | Current location (IP-based by default; can be overridden per-agent). |
docker_exec(container, command) | Run a command inside a running Docker container the agent has been granted access to. |
skill_read_file(skill, file) | Read a skill's supporting file (references/, templates/, scripts/, assets/). Companion to skill_evolve_*. |
docker_exec requires the agent to be in [capabilities] docker.* allowlist plus the container name in [exec_policy] docker_allowlist. Without both, calls reject with ToolError::Forbidden.
apply_patch Move Semantics
apply_patch accepts an UpdateFile { path, move_to, hunks } shape. When move_to is set, the patch first renames path to move_to, then applies the hunks against the new path. This collapses a rename + edit into a single tool call so the patch is atomic — readers never see the file at the old path post-rename.
Empty hunks with a non-null move_to is a pure rename. Useful when refactoring multiple files where one of them changes path but not contents.
skill_evolve_patch Fuzzy Matching
skill_evolve_patch modifies installed skills in-place. To survive small upstream drift, the matcher walks 5 strategies in order, first match wins:
- Exact — bytewise identical (Levenshtein 0).
- Line-trimmed — strip trailing whitespace and CRLFs from every line, then compare.
- Whitespace-normalised — collapse runs of intra-line whitespace; ignores tab vs. spaces drift.
- Indent-flexible — strip leading whitespace per line; ignores reformat-to-different-indent changes.
- Block-anchor — find a contiguous run of N anchor lines (default 3) in the target, splice the new content around them.
If all five fail, the patch is rejected with the exact diff context so the next turn can see what drifted. There's no automatic "best-effort" merge — fuzzy matching is bounded.
The companion tools skill_evolve_write_file and skill_evolve_remove_file manage skill supporting files (references/, templates/, scripts/, assets/) without going through patch semantics.
Where to Look in Code
- Tool registry —
crates/librefang-runtime/src/tools/— everyregister_tool!call. - Schema serialisation —
librefang-runtime::tools::schema— JSON schemas the LLM sees. - Capability gating —
librefang-runtime::capability— which agents can call which tools. - Browser pool —
crates/librefang-runtime/src/tools/browser/. - Schedule / cron runtime tools —
crates/librefang-runtime/src/tools/scheduler/.
When in doubt, the rustdoc on the tool struct is the canonical specification. The dashboard's "Tools" inspector also renders the live, agent-resolved tool set with current capability grants applied.