Autonomous Hands

LibreFang's core innovation — pre-built autonomous capability packages that run independently, executing tasks via LLM agents without human intervention.


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

HandFunctionType
ClipYouTube video download, clipping, subtitle generationMulti-agent
CreatorAI media studio — image, video, music, and speech generationMulti-agent
LeadDaily lead discovery, enrichment, 0-100 scoring, deduplicationMulti-agent
CollectorOSINT intelligence collection, change detection, knowledge graphMulti-agent
PredictorSuperforecasting engine, confidence intervals, contrarian patternsSingle-agent
ResearcherDeep autonomous research, CRAAP credibility assessment, APA citationMulti-agent
TwitterAutonomous X/Twitter account management, content formats, approval queueMulti-agent
BrowserWeb automation via Playwright, mandatory purchase approval gateSingle-agent
AnalyticsBusiness analytics, KPI tracking, automated reportingMulti-agent
ApiTesterAutomated API testing, contract validation, regression detectionSingle-agent
DevOpsCI/CD monitoring, deployment automation, infrastructure alerts, auto-evolution (PR review + BMAD bug/feature pipeline)Multi-agent
LinkedInLinkedIn profile monitoring, outreach automationMulti-agent
RedditReddit community monitoring, post scheduling, sentiment trackingMulti-agent
StrategistStrategic analysis, competitive intelligence, scenario planningMulti-agent
TraderMarket data monitoring, signal generation, portfolio trackingMulti-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

StatusDescription
ActiveRunning, agents spawned
PausedPaused, can be resumed
ErrorError occurred, intervention needed
InactiveNot 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

EndpointMethodDescription
/api/handsGETList all registered hands with status
/api/hands/activeGETList currently active hand instances
/api/hands/{hand_id}GETGet details for a specific hand
/api/hands/{hand_id}/activatePOSTActivate a hand (spawns agents)
/api/hands/{hand_id}/check-depsPOSTCheck dependency availability
/api/hands/{hand_id}/install-depsPOSTInstall missing dependencies
/api/hands/reloadPOSTReload hand definitions from disk

Hand Configuration

EndpointMethodDescription
/api/hands/{hand_id}/settingsGETGet current hand configuration
/api/hands/{hand_id}/settingsPUTUpdate hand configuration

Instance Lifecycle

EndpointMethodDescription
/api/hands/instances/{id}/pausePOSTPause a running hand instance
/api/hands/instances/{id}/resumePOSTResume a paused hand instance
/api/hands/instances/{id}DELETEDeactivate and remove a hand instance
/api/hands/instances/{id}/messagePOSTSend 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"}'