Autonomous Hands
LibreFang's core innovation — pre-built autonomous capability packages that run independently, executing tasks via LLM agents without human intervention.
Tip: Hands are activated through the CLI or REST API. Each hand spawns one or more agents that can be chatted with interactively.
Overview
Hands are LibreFang's unique feature — they are autonomous agents that can:
- Execute tasks automatically via LLM-powered agents
- Handle complex multi-step workflows
- Be configured through settings (provider, model, API keys)
- Operate as single-agent or multi-agent systems
Built-in Hands
| Hand | Function | Type |
|---|---|---|
| Clip | YouTube video download, clipping, subtitle generation | Multi-agent |
| Creator | AI media studio — image, video, music, and speech generation | Multi-agent |
| Lead | Daily lead discovery, enrichment, 0-100 scoring, deduplication | Multi-agent |
| Collector | OSINT intelligence collection, change detection, knowledge graph | Multi-agent |
| Predictor | Superforecasting engine, confidence intervals, contrarian patterns | Single-agent |
| Researcher | Deep autonomous research, CRAAP credibility assessment, APA citation | Multi-agent |
| Autonomous X/Twitter account management, content formats, approval queue | Multi-agent | |
| Browser | Web automation via Playwright, mandatory purchase approval gate | Single-agent |
| Analytics | Business analytics, KPI tracking, automated reporting | Multi-agent |
| ApiTester | Automated API testing, contract validation, regression detection | Single-agent |
| DevOps | CI/CD monitoring, deployment automation, infrastructure alerts, auto-evolution (PR review + BMAD bug/feature pipeline) | Multi-agent |
| LinkedIn profile monitoring, outreach automation | Multi-agent | |
| Reddit community monitoring, post scheduling, sentiment tracking | Multi-agent | |
| Strategist | Strategic analysis, competitive intelligence, scenario planning | Multi-agent |
| Trader | Market data monitoring, signal generation, portfolio tracking | Multi-agent |
CLI Commands
Hand Management
# List all available hands
librefang hand list
# Show currently active hand instances
librefang hand active
# Show status for a specific hand
librefang hand status clip
# Show detailed info about a hand
librefang hand info clip
# Reload hand definitions from disk
librefang hand reload
Activation Lifecycle
# Activate a hand
librefang hand activate clip
# Pause a running hand
librefang hand pause clip
# Resume a paused hand
librefang hand resume clip
# Deactivate a hand
librefang hand deactivate clip
Configuration
# Show current settings for a hand
librefang hand settings clip
# Set a configuration value
librefang hand set clip stt_provider groq
Interaction
# Chat with an active hand interactively
librefang hand chat clip
Dependencies
# Check dependency status
librefang hand check-deps clip
# Install missing dependencies
librefang hand install-deps clip
Local Installation
# Install a hand from a local directory
librefang hand install ./my-hand
Hand Status
| Status | Description |
|---|---|
| Active | Running, agents spawned |
| Paused | Paused, can be resumed |
| Error | Error occurred, intervention needed |
| Inactive | Not activated |
HAND.toml Format
Single-Agent Hand
id = "my-hand"
version = "1.0.0"
name = "My Hand"
description = "What this hand does"
category = "content"
icon = "M"
tools = ["shell_exec", "web_fetch"]
[[requires]]
key = "ffmpeg"
label = "FFmpeg must be installed"
requirement_type = "binary"
check_value = "ffmpeg"
[[settings]]
key = "quality"
label = "Output Quality"
setting_type = "select"
default = "high"
[[settings.options]]
value = "high"
label = "High (1080p)"
[[settings.options]]
value = "low"
label = "Low (480p)"
[agent]
name = "my-hand-agent"
description = "Processes tasks"
system_prompt = "You are a task processing agent."
[agent.model]
provider = "anthropic"
model = "claude-sonnet-4-20250514"
max_tokens = 4096
temperature = 0.7
[dashboard]
metrics = []
[routing]
aliases = ["my-hand", "process"]
weak_aliases = ["task", "automate"]
Multi-Agent Hand
id = "research"
version = "2.0.0"
name = "Research Hand"
description = "Multi-agent research system"
category = "content"
tools = ["web_fetch"]
[agents.planner]
coordinator = true
invoke_hint = "Use planner for task decomposition"
name = "planner-agent"
description = "Plans research tasks"
model = "default"
system_prompt = "You plan and coordinate research tasks."
[agents.analyst]
name = "analyst-agent"
description = "Analyzes and synthesizes data"
provider = "groq"
model = "llama-3.3-70b-versatile"
system_prompt = "You analyze data and produce insights."
[dashboard]
metrics = []
Legacy Flat Format (Backward Compatible)
Single-agent hands can use flat fields instead of [agent.model]:
[agent]
name = "my-agent"
description = "Simple agent"
provider = "anthropic"
model = "claude-sonnet-4-20250514"
max_tokens = 4096
temperature = 0.7
system_prompt = "You are a helpful agent."
Scheduling
A role wakes up on its own only if its own section says so, in one of exactly two ways. Every other role stays reactive: it runs when a message or event arrives, and never on a timer.
An explicit schedule wins over everything, verbatim.
It is the only way to reach a cron (periodic) or condition-driven (proactive) schedule.
ScheduleMode is externally tagged, so the struct variants need a sub-table — a bare schedule = "continuous" string does not parse, while the unit variant schedule = "reactive" does.
[agents.monitor.schedule.continuous]
check_interval_secs = 1800
An explicit [autonomous] block wakes the role at its own heartbeat_interval_secs (30s if the block omits it):
[agents.monitor.autonomous]
max_iterations = 40
heartbeat_interval_secs = 900
Writing both is allowed and the schedule decides the cadence — [autonomous] then only supplies the guardrails the role runs under once awake.
To keep those guardrails while switching the wake-up cycle off, write schedule = "reactive" alongside the block.
max_iterations on its own is a loop-depth cap — the ceiling on tool-call iterations within a single turn — and has no scheduling effect:
[agents.main]
name = "main-agent"
# Cap the turn's tool loop.
# This role still only runs when it is messaged.
max_iterations = 80
[metadata] frequency is catalog-display metadata for the marketplace listing and does not control scheduling:
[metadata]
# continuous | hourly | daily | periodic | on-demand
# "on-demand" is the default; "reactive" is accepted as a spelling of it.
frequency = "continuous"
Shell Exec Policy
A hand whose tools list contains shell_exec (or the * wildcard) inherits the daemon's global [exec_policy], mode included.
Activation never grants a stronger mode than the operator configured.
The default global mode is allowlist with an empty allowed_commands and a read-only safe_bins set, so a hand that needs to run real commands needs either an operator-side allowed_commands entry or its own declaration:
[agents.main.exec_policy]
mode = "allowlist"
allowed_commands = ["git", "cargo"]
timeout_secs = 600
A policy the hand declares is honoured verbatim, which keeps an elevated exec posture visible in the hand's own manifest instead of being an invisible activation-time grant.
The exec policy is resolved when the hand is activated, so an edit to it takes effect the next time the hand is activated.
The schedule is resolved earlier, when the HAND.toml is parsed into the registry — at daemon start and on POST /api/hands/reload — so an edit to schedule or [autonomous] needs that reload (or a daemon restart, which re-parses every definition and re-activates every persisted hand) before a re-activation can pick it up.
REST API Endpoints
Hand Discovery
| Endpoint | Method | Description |
|---|---|---|
/api/hands | GET | List all registered hands with status |
/api/hands/active | GET | List currently active hand instances |
/api/hands/{hand_id} | GET | Get details for a specific hand |
/api/hands/{hand_id}/activate | POST | Activate a hand (spawns agents) |
/api/hands/{hand_id}/check-deps | POST | Check dependency availability |
/api/hands/{hand_id}/install-deps | POST | Install missing dependencies |
/api/hands/reload | POST | Reload hand definitions from disk |
Hand Configuration
| Endpoint | Method | Description |
|---|---|---|
/api/hands/{hand_id}/settings | GET | Get current hand configuration |
/api/hands/{hand_id}/settings | PUT | Update hand configuration |
Instance Lifecycle
| Endpoint | Method | Description |
|---|---|---|
/api/hands/instances/{id}/pause | POST | Pause a running hand instance |
/api/hands/instances/{id}/resume | POST | Resume a paused hand instance |
/api/hands/instances/{id} | DELETE | Deactivate and remove a hand instance |
/api/hands/instances/{id}/message | POST | Send a message to a hand instance |
Example: Activate and Chat
# Activate
curl -X POST http://127.0.0.1:4545/api/hands/clip/activate
# Send a message
curl -X POST http://127.0.0.1:4545/api/hands/instances/<instance-id>/message \
-H "Content-Type: application/json" \
-d '{"message": "Download this video and generate subtitles"}'