The provider creation form only collected api_key_env (the env var name) but not the actual key value. New providers were always created as "unconfigured" because no key was stored. Add an optional secret api_key field so the dashboard can pass the key value during creation. The backend strips it from the TOML and saves it to secrets.env instead.
907 lines
24 KiB
TOML
907 lines
24 KiB
TOML
# 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.context_window]
|
|
type = "number"
|
|
required = true
|
|
description = "Maximum input tokens"
|
|
example = 128000
|
|
|
|
[provider.sections.models.fields.max_output_tokens]
|
|
type = "number"
|
|
required = true
|
|
description = "Maximum output tokens"
|
|
example = 16384
|
|
|
|
[provider.sections.models.fields.input_cost_per_m]
|
|
type = "number"
|
|
required = true
|
|
description = "USD per million 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 output tokens (0.0 for free/local)"
|
|
example = 10.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/<name>/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/<name>/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 = "integrations/<name>.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/<name>/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/<name>/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"
|