Skip to content

Plugin Configuration

A well-designed plugin typically needs to provide some configurable options, allowing users to adjust the plugin's behavior according to their needs, or provide necessary credentials (such as API keys). Nekro Agent provides a powerful plugin configuration system based on Pydantic models that can automatically generate user-friendly WebUI management interfaces.

Why is Configuration Needed?

  • Flexibility: Allows users to adjust plugin parameters to adapt to different scenarios.
  • Security: Avoids hardcoding sensitive information (such as API keys, passwords) in code.
  • Maintainability: When plugins need to be updated or deployed to different environments, configuration items are more convenient than modifying code.
  • User-Friendly: Through WebUI, non-technical users can also conveniently manage plugin settings.

Registering Configuration Classes

Plugin configuration is implemented by defining a class that inherits from nekro_agent.api.plugin.ConfigBase and registering it to the plugin instance using the @plugin.mount_config() decorator.

python
from nekro_agent.api.plugin import ConfigBase, ExtraField
from pydantic import Field, HttpUrl
from typing import List, Literal

@plugin.mount_config()
class MyPluginConfig(ConfigBase):
    """Configuration item definition for my plugin
    This is the overall description of the configuration class
    """

    # API key configuration (sensitive information)
    api_key: str = Field(
        default="",
        title="Service API Key",
        description="Please enter the API key obtained from the third-party service. This is required.",
        json_schema_extra=ExtraField(is_secret=True, required=True).model_dump()
    )

    # Basic numeric configuration
    max_items: int = Field(
        default=10,
        title="Maximum Number of Items to Process",
        description="The maximum number of items allowed for a single operation.",
    )

    # URL configuration
    service_url: str = Field(
        default="https://api.example.com/v1",
        title="Service Endpoint URL",
        description="The URL of the external service that the plugin will connect to.",
        json_schema_extra=ExtraField(placeholder="https://api.example.com/v1").model_dump()
    )

    # Switch configuration
    enable_feature_x: bool = Field(
        default=True,
        title="Enable Feature X",
        description="Whether to enable feature X of the plugin."
    )

    # Enumeration selection configuration
    processing_mode: Literal["fast", "accurate", "balanced"] = Field(
        default="balanced",
        title="Processing Mode",
        description="Select the plugin's processing mode: fast, accurate, or balanced."
    )

    # Model group reference configuration
    model_group: str = Field(
        default="default-chat",
        title="Model Group to Use",
        description="Select the chat model group to be used by the plugin",
        json_schema_extra=ExtraField(ref_model_groups=True, model_type="chat", required=True).model_dump()
    )

    # Multi-line text configuration
    system_prompt: str = Field(
        default="You are an intelligent assistant",
        title="System Prompt",
        description="System-level prompt used by the plugin, supports multi-line input",
        json_schema_extra=ExtraField(is_textarea=True, placeholder="Enter system prompt...").model_dump()
    )

    # User list configuration
    allowed_user_ids: List[str] = Field(
        default=[],
        title="Allowed User ID List",
        description="Only user IDs in this list can use specific features of this plugin (leave empty to not restrict).",
        json_schema_extra=ExtraField(
            is_textarea=True, 
            placeholder="Please enter user ID",
            sub_item_name="User"
        ).model_dump()
    )

    # Configuration requiring restart
    cache_size: int = Field(
        default=1000,
        title="Cache Size",
        description="Set the memory cache size of the plugin (restart required after modification)",
        json_schema_extra=ExtraField(is_need_restart=True).model_dump()
    )

    # Hidden advanced configuration (can only be modified through configuration files)
    debug_mode: bool = Field(
        default=False,
        title="Debug Mode",
        description="Enable detailed debug log output (for developer use only)",
        json_schema_extra=ExtraField(is_hidden=True).model_dump()
    )

    # More configuration items...

Key Points:

  • The configuration class must inherit from ConfigBase.
  • Use the @plugin.mount_config() decorator above the class definition.
  • The class-level docstring will serve as the overall description of the configuration page.
  • Each configuration item should be a class attribute and be defined in detail using Pydantic's Field.

Defining Configuration Items (Field)

Pydantic's Field is used to provide default values, type constraints, descriptions, and control the display and behavior of configuration items in the WebUI.

Common Parameters for Field:

  • default: The default value of the configuration item. If the user does not provide a value, this default value will be used.
  • title (str): The name (label) of the configuration item displayed in the WebUI. If not provided, it will be automatically generated based on the attribute name.
  • description (str): Detailed description of the configuration item, which will be displayed in the WebUI as prompt information. Simple HTML tags, such as links (<a>), can be included.
  • json_schema_extra: Used to pass additional WebUI control parameters. It is now recommended to use the ExtraField model to generate these, rather than manually constructing dictionaries. ExtraField provides the following attributes:
    • is_secret (bool): Sensitive information protection, when set to True, the input box displays as a password form
    • is_hidden (bool): Configuration item visibility control, when set to True, it is hidden in the WebUI
    • is_textarea (bool): Multi-line text support, when set to True, uses a multi-line text area
    • placeholder (str): Input prompt text, displays placeholder text in the input box
    • required (bool): Required field identifier, when set to True, frontend validation must be filled
    • ref_model_groups (bool): Model group reference identifier, when set to True, selects from system model groups
    • model_type (str): Model type specification, optional values are chat, embedding, draw
    • overridable (bool): Overridable field identifier, allows independent override at adapter or channel level
    • sub_item_name (str): Sub-item name, element name of list-type configuration items
    • load_to_sysenv (bool): Environment variable loading control, loads to system environment variables
    • load_sysenv_as (str): Environment variable name definition, specifies the variable name when loading
    • load_to_nonebot_env (bool): nonebot environment variable loading control
    • load_nbenv_as (str): nonebot environment variable name definition
    • is_need_restart (bool): Restart requirement identifier, requires application restart to take effect after modification

Supported Field Types and WebUI Rendering

Nekro Agent's configuration interface automatically renders appropriate input controls based on the field types of Pydantic models:

Python TypePydantic Type ExampleWebUI Control
StringstrText Input Box
IntegerintNumber Input Box
FloatfloatNumber Input Box (with decimal)
BooleanboolSwitch (Toggle)
Enumeration (fixed options)Literal["a", "b"]Dropdown Selection Box
String ListList[str]Tag Input Box
DictionaryDict[str, Any]Not available yet

Detailed Examples of Using ExtraField

Basic Usage

python
from nekro_agent.api.plugin import ConfigBase, ExtraField

# Simple sensitive information configuration
api_key: str = Field(
    default="",
    title="API Key",
    description="API key of the service",
    json_schema_extra=ExtraField(is_secret=True, required=True).model_dump()
)

# Multi-line text configuration
prompt_template: str = Field(
    default="",
    title="Prompt Template", 
    description="Custom prompt template",
    json_schema_extra=ExtraField(
        is_textarea=True,
        placeholder="Please enter prompt template..."
    ).model_dump()
)

# Model group selection configuration
model_group: str = Field(
    default="default-chat",
    title="Chat Model Group",
    description="Select the model group for chat",
    json_schema_extra=ExtraField(
        ref_model_groups=True,
        model_type="chat",
        required=True
    ).model_dump()
)

Advanced Functionality Examples

python
# Configuration requiring restart to take effect
thread_count: int = Field(
    default=4,
    title="Thread Count",
    description="Number of threads for concurrent processing (restart required after modification)",
    json_schema_extra=ExtraField(is_need_restart=True).model_dump()
)

# Overridable configuration item
timeout: int = Field(
    default=30,
    title="Request Timeout",
    description="Timeout for API requests (seconds)",
    json_schema_extra=ExtraField(overridable=True).model_dump()
)

# Environment variable loading configuration
debug_level: str = Field(
    default="INFO",
    title="Debug Level",
    description="System log debug level",
    json_schema_extra=ExtraField(
        load_to_sysenv=True,
        load_sysenv_as="LOG_LEVEL"
    ).model_dump()
)

Accessing Configuration

Once the configuration class is registered, you can access the instance of the configuration class through the plugin.config property anywhere in the plugin, and then access each configuration item.

python
@plugin.mount_sandbox_method(SandboxMethodType.TOOL, "perform_action", "Perform an operation that requires configuration.")
async def my_action(ctx: AgentCtx, some_input: str) -> str:
    # Access configuration items
    api_key = plugin.config.api_key
    max_items = plugin.config.max_items
    service_url = plugin.config.service_url

    if not api_key:
        return "Error: API key not configured. Please go to the plugin configuration page to set it up."

    # Use configuration items to perform operations
    # response = await some_api_call(service_url, api_key, some_input, limit=max_items)
    
    return f"Processed '{some_input}' on '{service_url}' using API key '{api_key[:4]}...' with a maximum of {max_items} items."

Best Practices

  1. Provide Reasonable Default Values: Ensure that the plugin can run in a safe or basically usable way when users have not made any configuration (if possible).
  2. Clear title and description: This is key for users to understand the purpose of configuration items. Descriptions should be as detailed as possible, explaining expected values, formats, where to obtain them, etc.
  3. Sensitive Data Marking: For API keys, passwords, etc., be sure to use json_schema_extra=ExtraField(is_secret=True).model_dump().
  4. Graceful Degradation: When certain configuration items are missing or invalid, the plugin should try to handle gracefully (for example, disable features that depend on the configuration and give clear prompts) instead of crashing directly.
  5. Hot Configuration Updates: Nekro Agent usually supports immediate effect of configuration without restarting the plugin or Agent. When accessing plugin.config in plugin code, what is obtained is usually the latest configuration value.

By carefully designing plugin configuration, you can greatly improve the usability, flexibility, and security of the plugin.