# LibreFang Registry Schema # ========================= # Machine-parseable schema definition for all registry content types. # Consumed by the RegistrySchema Rust type (librefang-types). # ═══════════════════════════════════════════════════════════════════════════════ # PROVIDER / MODEL SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [provider] description = "LLM provider configuration" file_pattern = "providers/*.toml" [provider.fields.id] type = "string" required = true description = "Unique provider identifier (lowercase, hyphenated)" example = "anthropic" [provider.fields.display_name] type = "string" required = true description = "Human-readable display name" example = "Anthropic" [provider.fields.api_key_env] type = "string" required = true description = "Environment variable name for the API key" example = "PROVIDER_API_KEY" [provider.fields.base_url] type = "string" required = true description = "Default API base URL" example = "https://api.example.com" [provider.fields.key_required] type = "bool" required = true description = "Whether an API key is needed (false for local providers)" example = true [provider.fields.api_key] type = "string" required = false description = "API key value (stored securely in secrets.env, not in the TOML file)" secret = true # --- Provider: nested [[models]] section --- [provider.sections.models] description = "Model entries" repeatable = true [provider.sections.models.fields.id] type = "string" required = true description = "Unique model identifier (API model ID)" example = "claude-sonnet-4-20250514" [provider.sections.models.fields.display_name] type = "string" required = true description = "Human-readable display name" example = "Claude Sonnet" [provider.sections.models.fields.tier] type = "string" required = true description = "Capability tier: frontier (cutting-edge, most capable), smart (cost-effective), balanced (speed/cost), fast (cheapest for simple tasks), local (Ollama, vLLM, LM Studio)" options = ["frontier", "smart", "balanced", "fast", "local"] example = "smart" [provider.sections.models.fields.modality] type = "string" required = false description = "Model modality. 'text' (default) is a chat/LLM; 'image' is an image-generation model (context_window/max_output_tokens become optional); 'audio' is a speech model." options = ["text", "image", "audio"] default = "text" example = "text" [provider.sections.models.fields.context_window] type = "number" required = true description = "Maximum input tokens. Required for modality='text'; optional for image/audio models where no published context gate exists." example = 128000 [provider.sections.models.fields.max_output_tokens] type = "number" required = true description = "Maximum output tokens. Required for modality='text'; optional for image/audio models." example = 16384 [provider.sections.models.fields.input_cost_per_m] type = "number" required = true description = "USD per million text input tokens (0.0 for free/local)" example = 2.5 [provider.sections.models.fields.output_cost_per_m] type = "number" required = true description = "USD per million text output tokens (0.0 for free/local)" example = 10.0 [provider.sections.models.fields.image_input_cost_per_m] type = "number" required = false description = "USD per million image input tokens (for image/multimodal models)" example = 8.0 [provider.sections.models.fields.image_output_cost_per_m] type = "number" required = false description = "USD per million image output tokens (for image-generation models)" example = 30.0 [provider.sections.models.fields.last_verified] type = "string" required = false description = "ISO date when pricing was last verified against official sources" example = "2025-03-15" [provider.sections.models.fields.supports_tools] type = "bool" required = false description = "Tool/function calling support" default = false [provider.sections.models.fields.supports_vision] type = "bool" required = false description = "Vision/image input support" default = false [provider.sections.models.fields.supports_streaming] type = "bool" required = false description = "Streaming response support" default = true [provider.sections.models.fields.supports_thinking] type = "bool" required = false description = "Extended thinking / reasoning support" default = false [provider.sections.models.fields.aliases] type = "array" required = false description = "Alternative names for this model" item_type = "string" example = ["alias1", "alias2"] # ═══════════════════════════════════════════════════════════════════════════════ # AGENT SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [agent] description = "Agent configuration" file_pattern = "agents//agent.toml" [agent.fields.name] type = "string" required = true description = "Agent identifier, must match directory name" example = "agent-name" [agent.fields.version] type = "string" required = false description = "Semver version string" example = "0.1.0" [agent.fields.description] type = "string" required = true description = "One-sentence description of what this agent does" example = "What this agent does" [agent.fields.author] type = "string" required = false description = "Author or organization" example = "author-name" [agent.fields.module] type = "string" required = true description = "Runtime module (builtin:chat, builtin:tool, etc.)" example = "builtin:chat" # --- Agent: [model] section --- [agent.sections.model] description = "Agent's LLM configuration" repeatable = false [agent.sections.model.fields.provider] type = "string" required = false description = "Provider ID or \"default\"" example = "default" [agent.sections.model.fields.model] type = "string" required = false description = "Model ID or \"default\"" example = "default" [agent.sections.model.fields.max_tokens] type = "number" required = false description = "Max response tokens" example = 4096 [agent.sections.model.fields.temperature] type = "number" required = false description = "Sampling temperature (0.0-2.0)" example = 0.7 [agent.sections.model.fields.system_prompt] type = "string" required = true description = "Behavioral instructions for the agent" # --- Agent: [metadata.routing] section --- [agent.sections.metadata] description = "Agent metadata" repeatable = false [agent.sections.metadata.sections.routing] description = "Routing configuration" repeatable = false [agent.sections.metadata.sections.routing.fields.aliases] type = "array" required = false description = "Phrases that route directly to this agent" item_type = "string" example = ["exact match phrases"] [agent.sections.metadata.sections.routing.fields.weak_aliases] type = "array" required = false description = "Keywords that suggest this agent" item_type = "string" example = ["partial match keywords"] # --- Agent: [resources] section --- [agent.sections.resources] description = "Resource limits" repeatable = false [agent.sections.resources.fields.max_llm_tokens_per_hour] type = "number" required = false description = "Token budget per hour" example = 100000 # --- Agent: [capabilities] section --- [agent.sections.capabilities] description = "Agent permissions" repeatable = false [agent.sections.capabilities.fields.tools] type = "array" required = false description = "List of allowed tool names" item_type = "string" example = ["tool1", "tool2"] [agent.sections.capabilities.fields.network] type = "array" required = false description = "Network access patterns (\"*\" = unrestricted)" item_type = "string" example = ["*"] [agent.sections.capabilities.fields.memory_read] type = "array" required = false description = "Memory read permissions" item_type = "string" example = ["*"] [agent.sections.capabilities.fields.memory_write] type = "array" required = false description = "Memory write permissions" item_type = "string" example = ["self.*"] [agent.sections.capabilities.fields.agent_spawn] type = "bool" required = false description = "Whether this agent can spawn sub-agents" default = false # ═══════════════════════════════════════════════════════════════════════════════ # HAND SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [hand] description = "Hand configuration (a hand is a user-facing capability backed by an agent)" file_pattern = "hands//HAND.toml" [hand.fields.id] type = "string" required = true description = "Unique identifier, must match directory name" example = "hand-id" [hand.fields.name] type = "string" required = true description = "Human-readable display name" example = "Hand Name" [hand.fields.description] type = "string" required = true description = "One-sentence description of what this hand does" example = "What this hand does" [hand.fields.category] type = "string" required = true description = "Hand category" options = [ "communication", "content", "data", "development", "devops", "finance", "productivity", "research", "social", ] example = "productivity" [hand.fields.icon] type = "string" required = false description = "Emoji icon" [hand.fields.tools] type = "array" required = true description = "List of tool names this hand uses" item_type = "string" example = ["tool1", "tool2"] # --- Hand: [routing] section --- [hand.sections.routing] description = "Routing configuration" repeatable = false [hand.sections.routing.fields.aliases] type = "array" required = false description = "Phrases that activate this hand" item_type = "string" example = ["activate phrases"] [hand.sections.routing.fields.weak_aliases] type = "array" required = false description = "Keyword hints for routing" item_type = "string" example = ["keyword hints"] # --- Hand: [[requires]] section --- [hand.sections.requires] description = "External dependencies" repeatable = true [hand.sections.requires.fields.key] type = "string" required = true description = "Unique dependency key" example = "python3" [hand.sections.requires.fields.label] type = "string" required = true description = "Human-readable label" example = "Python 3" [hand.sections.requires.fields.requirement_type] type = "string" required = true description = "Type of requirement" options = ["binary", "package", "service"] example = "binary" [hand.sections.requires.fields.check_value] type = "string" required = true description = "Binary name or check command" example = "python3" [hand.sections.requires.fields.optional] type = "bool" required = false description = "Whether the dependency is optional" default = false [hand.sections.requires.fields.description] type = "string" required = false description = "Why this dependency is needed" # --- Hand: [[requires]] -> [install] nested section --- [hand.sections.requires.sections.install] description = "Platform-specific install instructions" repeatable = false [hand.sections.requires.sections.install.fields.macos] type = "string" required = false description = "macOS install command" example = "brew install python3" [hand.sections.requires.sections.install.fields.windows] type = "string" required = false description = "Windows install command" example = "winget install Python.Python.3.12" [hand.sections.requires.sections.install.fields.linux_apt] type = "string" required = false description = "Linux (apt) install command" example = "sudo apt install python3" [hand.sections.requires.sections.install.fields.manual_url] type = "string" required = false description = "URL for manual installation instructions" example = "https://..." # --- Hand: [[settings]] section --- [hand.sections.settings] description = "User-configurable settings" repeatable = true [hand.sections.settings.fields.key] type = "string" required = true description = "Unique setting key" example = "setting_key" [hand.sections.settings.fields.label] type = "string" required = true description = "Human-readable label" example = "Setting Label" [hand.sections.settings.fields.description] type = "string" required = false description = "What this setting controls" [hand.sections.settings.fields.setting_type] type = "string" required = true description = "Setting input type" options = ["toggle", "select", "text", "number"] example = "toggle" [hand.sections.settings.fields.default] type = "string" required = false description = "Default value as string" example = "true" # --- Hand: [[settings]] -> [[options]] nested section --- [hand.sections.settings.sections.options] description = "Available options for select-type settings" repeatable = true [hand.sections.settings.sections.options.fields.value] type = "string" required = true description = "Option value" example = "option1" [hand.sections.settings.sections.options.fields.label] type = "string" required = true description = "Option display label" example = "Option Label" # --- Hand: [agent] section --- [hand.sections.agent] description = "The agent that powers this hand" repeatable = false [hand.sections.agent.fields.name] type = "string" required = true description = "Agent name" example = "hand-agent-name" [hand.sections.agent.fields.description] type = "string" required = false description = "Agent description" [hand.sections.agent.fields.module] type = "string" required = true description = "Runtime module" example = "builtin:chat" [hand.sections.agent.fields.provider] type = "string" required = false description = "Provider ID" example = "default" [hand.sections.agent.fields.model] type = "string" required = false description = "Model ID" example = "default" [hand.sections.agent.fields.max_tokens] type = "number" required = false description = "Max response tokens" example = 16384 [hand.sections.agent.fields.temperature] type = "number" required = false description = "Sampling temperature" example = 0.3 [hand.sections.agent.fields.max_iterations] type = "number" required = false description = "Maximum tool-use iterations" example = 60 [hand.sections.agent.fields.system_prompt] type = "string" required = true description = "Detailed behavioral prompt for the agent" # --- Hand: [dashboard] section --- [hand.sections.dashboard] description = "Dashboard metrics configuration" repeatable = false # --- Hand: [dashboard] -> [[metrics]] nested section --- [hand.sections.dashboard.sections.metrics] description = "Dashboard metric entries" repeatable = true [hand.sections.dashboard.sections.metrics.fields.label] type = "string" required = true description = "Metric display name" example = "Metric Name" [hand.sections.dashboard.sections.metrics.fields.memory_key] type = "string" required = true description = "Memory key to read the metric value from" example = "metric_memory_key" [hand.sections.dashboard.sections.metrics.fields.format] type = "string" required = true description = "Display format for the metric value" options = ["number", "currency", "percentage"] example = "number" # --- Hand: [metadata] section --- [hand.sections.metadata] description = "Operational metadata" repeatable = false [hand.sections.metadata.fields.frequency] type = "string" required = false description = "How often this hand runs" options = ["continuous", "on-demand", "scheduled"] example = "continuous" [hand.sections.metadata.fields.token_consumption] type = "string" required = false description = "Expected token usage level" options = ["low", "medium", "high"] example = "low" [hand.sections.metadata.fields.default_active] type = "bool" required = false description = "Whether this hand is active by default" default = true # ═══════════════════════════════════════════════════════════════════════════════ # INTEGRATION SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [integration] description = "External service integration via MCP server" file_pattern = "mcp/.toml" [integration.fields.id] type = "string" required = true description = "Unique identifier, must match filename" example = "integration-id" [integration.fields.name] type = "string" required = true description = "Human-readable display name" example = "Service Name" [integration.fields.description] type = "string" required = false description = "One-sentence description of what this integration provides" [integration.fields.category] type = "string" required = false description = "Integration category" options = [ "devtools", "communication", "storage", "monitoring", "data", "productivity", ] example = "devtools" [integration.fields.icon] type = "string" required = false description = "Emoji icon" [integration.fields.tags] type = "array" required = false description = "Searchable tags" item_type = "string" example = ["tag1", "tag2"] [integration.fields.setup_instructions] type = "string" required = false description = "Multi-line setup guide" # --- Integration: [transport] section --- [integration.sections.transport] description = "MCP server transport configuration" repeatable = false [integration.sections.transport.fields.type] type = "string" required = true description = "Transport type" options = ["stdio", "sse"] example = "stdio" [integration.sections.transport.fields.command] type = "string" required = true description = "Command to launch the MCP server" example = "npx" [integration.sections.transport.fields.args] type = "array" required = false description = "Command arguments" item_type = "string" example = ["-y", "@pkg/server"] # --- Integration: [[required_env]] section --- [integration.sections.required_env] description = "Required environment variables" repeatable = true [integration.sections.required_env.fields.name] type = "string" required = true description = "Environment variable name" example = "SERVICE_API_KEY" [integration.sections.required_env.fields.label] type = "string" required = true description = "Human-readable label" example = "API Key" [integration.sections.required_env.fields.help] type = "string" required = false description = "Help text explaining how to get this value" [integration.sections.required_env.fields.is_secret] type = "bool" required = false description = "Whether this is a secret value" default = true [integration.sections.required_env.fields.get_url] type = "string" required = false description = "URL where user can obtain the value" example = "https://..." # --- Integration: [oauth] section --- [integration.sections.oauth] description = "OAuth configuration" repeatable = false [integration.sections.oauth.fields.provider] type = "string" required = true description = "OAuth provider identifier" example = "github" [integration.sections.oauth.fields.scopes] type = "array" required = false description = "OAuth scopes to request" item_type = "string" example = ["repo", "read:org"] [integration.sections.oauth.fields.auth_url] type = "string" required = false description = "OAuth authorization URL" example = "https://..." [integration.sections.oauth.fields.token_url] type = "string" required = false description = "OAuth token exchange URL" example = "https://..." # --- Integration: [health_check] section --- [integration.sections.health_check] description = "Health check configuration" repeatable = false [integration.sections.health_check.fields.interval_secs] type = "number" required = false description = "Health check interval in seconds" example = 60 [integration.sections.health_check.fields.unhealthy_threshold] type = "number" required = false description = "Number of consecutive failures before marking unhealthy" example = 3 # ═══════════════════════════════════════════════════════════════════════════════ # SKILL SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [skill] description = "Reusable skill definition (prompt template or script)" file_pattern = "skills//skill.toml" # --- Skill: [skill] section (metadata) --- # Note: the top-level "skill" content type contains a [skill] section for metadata. # In the TOML file, these fields live directly under [skill]. [skill.sections.skill] description = "Skill metadata" repeatable = false [skill.sections.skill.fields.name] type = "string" required = true description = "Skill identifier, must match directory name" example = "skill-name" [skill.sections.skill.fields.version] type = "string" required = false description = "Semver version string" example = "0.1.0" [skill.sections.skill.fields.description] type = "string" required = false description = "One-sentence description of what this skill does" [skill.sections.skill.fields.author] type = "string" required = false description = "Author or organization" example = "author-name" [skill.sections.skill.fields.tags] type = "array" required = false description = "Searchable tags" item_type = "string" example = ["tag1", "tag2"] # --- Skill: [runtime] section --- [skill.sections.runtime] description = "Execution runtime configuration" repeatable = false [skill.sections.runtime.fields.type] type = "string" required = true description = "Runtime type" options = ["promptonly", "python", "node", "shell"] example = "promptonly" [skill.sections.runtime.fields.entry] type = "string" required = false description = "Entry point file (required for non-promptonly runtimes)" example = "main.py" # --- Skill: [input] section --- [skill.sections.input] description = "Input parameter definitions (each field is a parameter with type, description, required)" repeatable = false # Note: input fields are dynamic — each key is a parameter name with an object value # containing type, description, and required. This section uses a convention where # individual parameters are defined as fields. # --- Skill: [prompt] section --- [skill.sections.prompt] description = "Prompt template (required for promptonly runtime)" repeatable = false [skill.sections.prompt.fields.template] type = "string" required = true description = "Prompt template string, supports {{param_name}} placeholders" example = "Use {{param_name}} in the template" # ═══════════════════════════════════════════════════════════════════════════════ # PLUGIN SCHEMA # ═══════════════════════════════════════════════════════════════════════════════ [plugin] description = "Plugin that extends agent behavior via lifecycle hooks" file_pattern = "plugins//plugin.toml" [plugin.fields.name] type = "string" required = true description = "Plugin identifier, must match directory name" example = "plugin-name" [plugin.fields.version] type = "string" required = true description = "Semver version string" example = "0.1.0" [plugin.fields.description] type = "string" required = true description = "One-sentence description of what this plugin does" [plugin.fields.author] type = "string" required = false description = "Author or organization" example = "author-name" # --- Plugin: [hooks] section --- # Hook scripts communicate via stdin/stdout JSON: # ingest receives: {"type": "ingest", "agent_id": "...", "message": "..."} # ingest returns: {"type": "ingest_result", "memories": [{"content": "..."}]} # after_turn receives: {"type": "after_turn", "agent_id": "...", "messages": [...]} # after_turn returns: {"type": "ok"} [plugin.sections.hooks] description = "Hook entry points — scripts invoked at specific lifecycle events" repeatable = false [plugin.sections.hooks.fields.ingest] type = "string" required = false description = "Script called when a user message is received" example = "hooks/ingest.py" [plugin.sections.hooks.fields.after_turn] type = "string" required = false description = "Script called after each conversation turn" example = "hooks/after_turn.py"