Base Class

A Compound Model class for managing plugins.

class smarter.apps.plugin.plugin.base.PluginBase(*args, user_profile=None, selected=False, api_version=None, manifest=None, plugin_id=None, plugin_meta=None, data=None, name=None, **kwargs)[source]

Bases: ABC, AccountMixin, SmarterConverterMixin

Abstract base class for Smarter plugins.

This class provides a comprehensive framework for managing plugin lifecycle, including creation, updating, deletion, cloning, and serialization. It integrates with Django ORM models and serializers, and supports manifest-based initialization using Pydantic models or YAML/JSON representations.

Initialization Options:

  • Via Pydantic model from a manifest broker (preferred).

  • By Django model plugin ID.

  • From YAML or JSON manifest representations.

Responsibilities

  • Manages plugin metadata, selector, prompt, and data models.

  • Handles serialization to JSON and YAML formats compatible with Smarter API.

  • Supports OpenAI function calling schema for plugin tools.

  • Provides hooks for plugin selection logic and prompt customization.

  • Ensures validation and readiness of plugin components.

  • Integrates with Django signals for plugin lifecycle events.

Usage

  • Subclass this base and implement all abstract properties and methods.

  • Use provided factory and utility methods for parameter and data conversion.

  • Leverage transaction management for safe database operations.

Notes

  • All subclasses must define the plugin data class, serializer, and manifest handling.

  • This class expects a valid UserProfile for most operations.

  • Exceptions are raised for misconfiguration or invalid states.

See the Smarter API documentation for details on plugin manifest structure and lifecycle.

SAMPluginType

alias of SAMPluginCommon

__init__(*args, user_profile=None, selected=False, api_version=None, manifest=None, plugin_id=None, plugin_meta=None, data=None, name=None, **kwargs)[source]

Initialize a PluginBase instance.

Key features:

  • Lazy instantiation of class properties.

  • Supports multiple initialization methods including manifest, database model, and YAML/JSON.

  • Integrates with Django ORM for plugin metadata management.

  • Utilizes Pydantic models for manifest validation and serialization.

  • Provides hooks for plugin selection and prompt customization.

  • Ensures plugin readiness and validation before use.

  • Sends signals upon plugin creation or update.

This constructor supports several ways to create a plugin object:

  • Manifest-based initialization:

    Pass a Pydantic model instance via the manifest argument. This is the preferred method and is typically used when loading plugins from a manifest broker.

  • Database model initialization:

    Provide a Django model plugin ID via plugin_id or a PluginMeta instance via plugin_meta to load an existing plugin from the database.

  • YAML/JSON manifest initialization:

    Supply a YAML or JSON string (or dictionary) via the data argument to create a plugin from a manifest representation.

See ./data/sample-plugins/everlasting-gobstopper.yaml for an example manifest.

The constructor sets up internal state, initializes plugin properties, and triggers plugin creation or update logic as needed. It also sends signals when the plugin is ready.

Parameters:
  • user_profile (Optional[UserProfile]) – The user profile associated with the plugin.

  • selected (bool) – Whether the plugin is initially selected.

  • api_version (Optional[str]) – The API version for the plugin manifest.

  • manifest (Optional[SAMPluginCommon]) – A Pydantic model representing the plugin manifest.

  • plugin_id (Optional[int]) – The Django ORM plugin ID.

  • plugin_meta (Optional[PluginMeta]) – The Django ORM PluginMeta instance.

  • data (Union[dict[str, Any], str, None]) – YAML/JSON manifest as a string or dictionary.

  • name (Optional[str]) – The name of the plugin.

  • kwargs – Additional keyword arguments.

property account: Account | None

Returns the account for the current user. Handle lazy instantiation from user or user_profile.

Returns:

The account for the current user.

Return type:

Account or None

property account_mixin_logger_prefix: str

Returns the logger prefix for the class.

property account_number: str | None

A helper function to get the account number from the account.

Returns:

The account number for the current account.

Return type:

str or None

property accountmixin_ready_state: str

Returns a string representation of the AccountMixin ready state.

Returns:

String representation of the AccountMixin ready state.

Return type:

str

property amnesty_urls: list[str]

Returns a list of URLs that are exempt from certain checks.

This is a placeholder and should be overridden in subclasses.

Returns:

List of URL path strings that are exempt.

Return type:

list[str]

property api_version: str

Return the api version of the plugin.

Returns:

The api version of the plugin.

Return type:

str

Raises:

SAMValidationError – If the api version is not valid.

See also

  • smarter.common.api.SmarterApiVersions

  • SMARTER_API_MANIFEST_COMPATIBILITY

authenticate(api_token)

Authenticate the user using the provided API token. The api_token will have been generated by the SmarterTokenAuthentication class and passed by the caller in the Authorization header of the request.

Example

Authorization: Token <api_token>

Parameters:

api_token (bytes) – The API token to authenticate with.

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

cache_invalidations()[source]

Invalidate cached properties related to the plugin.

This method is used to clear any cached data associated with the plugin instance, such as cached Django ORM model instances or serializers. It ensures that subsequent accesses to these properties will fetch fresh data from the database or re-instantiate serializers as needed.

The following properties are invalidated:

  • user_profile

  • plugin_meta

  • plugin_selector

  • plugin_prompt

  • plugin_data

Return type:

None

camel_to_snake(data)

Converts camelCase strings, dictionary keys, or lists of such, to snake_case format.

Parameters:

data (str, dict, or list) – The input to convert. Can be a string, a dictionary (with camelCase keys), or a list containing strings or dictionaries.

Returns:

The converted data in snake_case format. Returns a string, dictionary, or list, matching the input type.

Return type:

Optional[Union[str, dict, list]]

Note

  • For dictionaries, only keys are converted. Values are preserved as-is, except for nested dictionaries, which are also converted.

  • Spaces in keys are replaced with underscores.

  • Multiple consecutive underscores are collapsed into a single underscore.

  • Nested dictionaries and lists are processed recursively.

Warning

If the input is not a string, dictionary, or list, a SmarterValueError is raised.

Example usage:

from smarter.common.utils import camel_to_snake

# Convert a string
print(camel_to_snake("userName"))  # Output: user_name

# Convert a dictionary
data = {
    "userName": "alice",
    "userProfile": {
        "firstName": "Alice",
        "lastName": "Smith"
    }
}
print(camel_to_snake(data))
# Output: {'user_name': 'alice', 'user_profile': {'first_name': 'Alice', 'last_name': 'Smith'}}

# Convert a list of strings
print(camel_to_snake(["firstName", "lastName"]))
# Output: ['first_name', 'last_name']
clone(new_name=None)[source]

Clone a plugin.

Parameters:

new_name (Optional[str]) – The new name for the cloned plugin. If None, a name will be generated.

Returns:

The id of the cloned plugin if successful, False otherwise.

Return type:

Optional[int]

Raises:

SmarterPluginError – If the plugin is not ready.

create()[source]

Create a plugin from either yaml or a dictionary.

Returns:

True if the plugin was created successfully, False otherwise.

Return type:

bool

Raises:

SmarterPluginError – If the plugin manifest is not set.

property custom_tool: dict[str, Any][source]

Return the plugin tool definition for OpenAI function calling.

See the OpenAI documentation: https://platform.openai.com/docs/assistants/tools/function-calling/quickstart

Example:

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_temperature",
            "description": "Get the current temperature for a specific location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g., San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["Celsius", "Fahrenheit"],
                        "description": "The temperature unit to use. Infer this from the user's location."
                    }
                },
                "required": ["location", "unit"]
            }
        }
    }
]

See also

  • smarter.lib.openai.enum.OpenAIToolCall

  • smarter.lib.openai.enum.OpenAIToolTypes

customize_prompt(messages)[source]

Modify the system prompt based on the plugin object.

Parameters:

messages (list[dict]) – The list of messages to customize.

Returns:

The customized list of messages.

Return type:

list[dict]

property data: dict | None

Return the plugin as a dictionary.

Returns:

The plugin as a dictionary if ready, None otherwise.

Return type:

Optional[dict]

data_to_dict(data)

Converts data to a dictionary, handling different types of input.

This method accepts either a dictionary or a string. If a string is provided, it will attempt to parse it as JSON first, and if that fails, as YAML. If parsing fails or the data type is unsupported, a SmarterValueError is raised.

Parameters:

data (dict or str) – The data to convert, either a dict or a JSON/YAML string.

Returns:

The data as a dictionary.

Return type:

dict

Raises:

SmarterValueError – If the data cannot be converted to a dictionary.

delete()[source]

Delete a plugin.

Returns:

True if the plugin was deleted successfully, False otherwise.

Return type:

bool

Raises:

SmarterPluginError – If the plugin is not ready.

classmethod example_manifest(kwargs=None)[source]

Return an example manifest for the plugin. Must be implemented by subclasses.

Parameters:

kwargs (Optional[dict[str, Any]]) – Optional keyword arguments to customize the example manifest.

Returns:

NotImplementedError

Return type:

NotImplementedError

property formatted_class_name: str

Returns the class name in a formatted string along with the name of this mixin.

property formatted_pluginbase_class_name: str

Return the formatted class name for logging.

Returns:

The formatted class name.

Return type:

str

property formatted_state_not_ready: str

Returns the not-ready state formatted for logging.

Returns:

The formatted not-ready state as a string.

Return type:

str

property formatted_state_ready: str

Returns the readiness state formatted for logging.

Returns:

The formatted readiness state as a string.

Return type:

str

property function_calling_identifier: str

Return the function calling plugin.

Returns:

The function calling plugin identifier.

Return type:

str

Raises:

SmarterPluginError – If the plugin is not ready.

property function_parameters: dict[str, Any] | None

Fetch the function parameters from the Django model. Return the function parameters in a dictionary formatted according to the OpenAI function calling schema.

Returns:

The function parameters as a dictionary.

Return type:

Optional[dict[str, Any]]

property id: int | None

Return the Django ORM PluginMeta id.

Returns:

The id of the plugin.

Return type:

Optional[int]

property is_accountmixin_ready: bool

Returns True if the AccountMixin is ready to be used. This is a convenience property that checks if the account and user are initialized. AccountMixin is considered ready if: - self.user is an instance of User - self.user_profile is an instance of UserProfile - self.account is an instance of Account

Returns:

True if the AccountMixin is ready to be used.

Return type:

bool

property is_authenticated: bool

Returns True if the user is authenticated and is associated with an Account.

is_valid_yaml(data)[source]

Validate a yaml string.

Parameters:

data (str) – The yaml string to validate.

Returns:

True if the yaml string is valid, False otherwise.

Return type:

bool

property kind: str

Return the kind of the plugin.

Returns:

The kind of the plugin.

Return type:

str

See also

  • smarter.apps.plugin.manifest.models.static_plugin.const.MANIFEST_KIND

Example:

`python foo = MyPlugin() print(foo.kind) "SqlPlugin" `

log_account_mixin_ready_status()

Logs the ready status of the AccountMixin.

property manifest: SAMPluginCommon

Return the Pydandic model of the plugin.

Returns:

The Pydantic model of the plugin.

Return type:

SAMPluginCommon

mask_string(string='', mask_char='*', mask_length=4, string_length=8)

Masks a string for secure logging.

This utility function masks all but the last unmasked_chars characters of the input string, replacing them with asterisks. It is useful for logging sensitive information like API keys or passwords.

Parameters:
  • string (str) – The string to be masked.

  • mask_char (str) – The character used for masking.

  • mask_length (int) – The number of characters to mask.

  • string_length (int) – The length of the string to consider for masking.

Returns:

The masked string.

Return type:

str

property metadata_class: str | None

Return the metadata class, PluginMeta.plugin_class

Returns:

The metadata class name.

Return type:

Optional[str]

See also:

  • smarter.apps.plugin.models.PluginMeta

property name: str | None

Return the name of the plugin.

Returns:

The name of the plugin.

Return type:

Optional[str]

Raises:

SmarterPluginError – If the PluginMeta is not of the expected type.

classmethod parameter_factory(name, data_type, description, enum=None, required=False, default=None)[source]

Factory method to create a parameter dictionary for the SQL plugin.

Parameters:
  • name (str) – The name of the parameter.

  • data_type (str) – The data type of the parameter.

  • description (str) – The description of the parameter.

  • enum (Optional[list]) – An optional list of enumerated values for the parameter.

  • required (Optional[bool]) – Whether the parameter is required. Default is False.

  • default (Optional[Any]) – The default value of the parameter. Default is None.

Returns:

A dictionary representing the parameter.

Return type:

dict[str, Any]

property params: dict[str, Any] | None

Return the plugin parameters.

Returns:

The plugin parameters.

Return type:

Optional[dict[str, Any]]

Example:

`python foo = MyPlugin() print(foo.params) {"key": "value"} `

pascal_to_snake(name)

Converts a PascalCase string to pascal_case snake_case format.

Parameters:

name (str) – The PascalCase string to convert.

Returns:

The converted string in snake_case format.

Return type:

str

Note

  • Spaces in the input string are replaced with underscores.

  • Multiple consecutive underscores are collapsed into a single underscore.

Example usage:

from smarter.common.utils import pascal_to_snake

print(pascal_to_snake("UserProfile"))  # Output: user_profile
print(pascal_to_snake("FirstName LastName"))  # Output: first_name_last_name
abstract property plugin_data: PluginDataBase

Return the plugin data as a Django ORM instance.

This abstract property must be implemented by all subclasses of PluginBase. It should return an instance of the Django model that represents the plugin’s data. This instance is used for accessing and manipulating plugin-specific data stored in the database.

Returns:

The Django ORM model instance for plugin data.

Return type:

PluginDataBase

Raises:

NotImplementedError – If not implemented in a subclass.

abstract property plugin_data_class: type[PluginDataBase]

Return the Django ORM base class for plugin data.

This abstract property must be implemented by all subclasses. It should return the Django model class that represents the plugin’s data structure. This model is used for storing and retrieving plugin-specific data from the database.

Subclasses should ensure that the returned class inherits from PluginDataBase and defines all necessary fields for the plugin’s operation.

Returns:

The Django ORM model class for plugin data.

Return type:

type[PluginDataBase]

Raises:

NotImplementedError – If not implemented in a subclass.

Example:

from smarter.apps.plugin.plugin.base import PluginDataBase

class MyPluginData(PluginDataBase):
    # Define fields specific to MyPluginData
    pass

foo = MyPlugin()
assert foo.plugin_data_class == MyPluginData
abstract property plugin_data_django_model: dict

Return the plugin data definition as a json object.

Returns:

The plugin data definition as a dictionary.

Return type:

dict

Raises:

NotImplementedError – If not implemented in a subclass.

abstract property plugin_data_serializer: ModelSerializer

Return the plugin data serializer for the plugin data Django ORM.

Returns:

The serializer instance for the plugin data.

Return type:

serializers.ModelSerializer

Raises:

NotImplementedError – If not implemented in a subclass.

abstract property plugin_data_serializer_class: type[ModelSerializer]

Return the plugin data serializer class for the plugin data Django ORM.

Returns:

The serializer class for the plugin data.

Return type:

type[serializers.ModelSerializer]

Raises:

NotImplementedError – If not implemented in a subclass.

property plugin_meta: PluginMeta | None

Return the plugin meta.

Returns:

The plugin meta.

Return type:

Optional[PluginMeta]

Note

This property will attempt to load the PluginMeta from the database if it has not already been set and if the UserProfile and manifest are available.

property plugin_meta_django_model: dict[str, Any] | None

Return a dict for loading the plugin meta Django ORM model.

Returns:

The plugin meta definition as a json object.

Return type:

Optional[dict[str, Any]]

property plugin_meta_serializer: PluginMetaSerializer | None

Return the plugin meta serializer.

Returns:

The plugin meta serializer.

Return type:

Optional[PluginMetaSerializer]

property plugin_prompt: PluginPrompt | None

Return the plugin prompt.

Returns:

The plugin prompt.

Return type:

PluginPrompt

Raises:

SmarterPluginError – If the PluginPrompt does not exist.

property plugin_prompt_django_model: dict[str, Any] | None

Return the plugin prompt definition as a json object that can be used to load the Django ORM model.

Returns:

The plugin prompt definition as a dictionary.

Return type:

Optional[dict[str, Any]]

property plugin_prompt_serializer: PluginPromptSerializer | None

Return the plugin prompt serializer.

Returns:

The plugin prompt serializer.

Return type:

Optional[PluginPromptSerializer]

property plugin_selector: PluginSelector | None

Return the plugin selector.

Returns:

The plugin selector.

Return type:

Optional[PluginSelector]

property plugin_selector_django_model: dict[str, Any] | None

Return the plugin selector definition as a json object.

Returns:

The plugin selector definition as a dictionary.

Return type:

Optional[dict[str, Any]]

property plugin_selector_history: QuerySet | None

Return the plugin selector history serializer.

Returns:

The plugin selector history queryset.

Return type:

Optional[QuerySet]

property plugin_selector_serializer: PluginSelectorSerializer | None

Return the plugin selector serializer.

Returns:

The plugin selector serializer.

Return type:

Optional[PluginSelectorSerializer]

property ready: bool[source]

Return whether the plugin is ready.

Returns:

True if the plugin is ready, False otherwise.

Return type:

bool

Raises:

SmarterPluginError – If the UserProfile is not set or if any of the plugin components are not of the expected type.

property ready_state: str

Returns a string representation of the ready state.

refresh()[source]

Refresh the plugin.

Returns:

True if the plugin is ready after refresh, False otherwise.

Return type:

bool

reinitialize_plugin()[source]

Reset all plugin-related properties to None.

This method is used to clear the internal state of the plugin instance, including all cached references to Django ORM models, serializers, and other plugin-specific objects. It is typically called during initialization or when reloading a plugin to ensure that no stale data remains.

The following attributes are reset:

  • _plugin_meta: The plugin metadata model instance.

  • _plugin_selector: The plugin selector model instance.

  • _plugin_prompt: The plugin prompt model instance.

  • _plugin_selector_history: The queryset for selector history.

  • _plugin_data: The plugin data model instance.

  • _plugin_prompt_serializer: The serializer for the plugin prompt.

  • _plugin_selector_serializer: The serializer for the plugin selector.

  • _plugin_meta_serializer: The serializer for the plugin metadata.

This ensures that subsequent operations on the plugin will re-fetch or re-create these objects as needed, avoiding issues with outdated or invalid references.

rfc1034_compliant_str(val)

Generates a RFC 1034-compliant name string suitable for use as a DNS label or resource identifier.

Parameters:

val (str) – The input string to convert to RFC 1034-compliant format.

Returns:

A string that is: - lower case - contains only alphanumeric characters and hyphens - starts and ends with an alphanumeric character - has a maximum length of 63 characters

Return type:

str

Raises:

SmarterValueError – If the input is not a string or is empty after conversion.

Note

  • Underscores in the input are replaced with hyphens.

  • Invalid characters (anything other than a-z, 0-9, or ‘-’) are removed.

  • Leading and trailing hyphens are stripped.

  • The result is truncated to 63 characters if necessary.

Warning

This function is intended for generating DNS-safe names. It does not guarantee uniqueness or suitability for all RFC 1034 use cases.

Example usage:

from smarter.common.utils import rfc1034_compliant_str

# Basic usage
print(rfc1034_compliant_str("My_ChatBot_2025"))  # Output: my-chatbot-2025

# With special characters
print(rfc1034_compliant_str("My@Bot!_Name"))  # Output: my-bot-name

# With long input
long_name = "ThisIsAReallyLongChatBotNameThatShouldBeTruncatedToSixtyThreeCharacters_Extra"
print(rfc1034_compliant_str(long_name))  # Output: thisisareallylongchatbotnamethatshouldbetruncatedtosixtythreecharacters
rfc1034_compliant_to_snake(val)

Converts a RFC 1034-compliant name (typically used for DNS labels or resource identifiers) to a more human-readable snake_case name.

This function is useful for translating machine-friendly names (which use hyphens as word separators) into Pythonic identifiers (which use underscores).

Parameters:

val (str) – The RFC 1034-compliant name to convert. This should be a string containing only lowercase letters, numbers, and hyphens.

Returns:

The converted name in snake_case format, with hyphens replaced by underscores.

Return type:

str

Raises:

SmarterValueError – If the input is not a string.

Note

  • Only hyphens are replaced; other characters are preserved.

  • The function does not validate that the input is strictly RFC 1034-compliant. It assumes the input is already sanitized.

Warning

This function does not handle conversion of other non-alphanumeric characters. If the input contains characters other than hyphens, underscores, letters, or numbers, they will remain unchanged.

Example usage:

from smarter.common.utils import rfc1034_compliant_to_snake

# Basic conversion
print(rfc1034_compliant_to_snake("my-chatbot-2025"))
# Output: my_chatbot_2025

# Input with no hyphens
print(rfc1034_compliant_to_snake("simplelabel"))
# Output: simplelabel

# Input with multiple hyphens
print(rfc1034_compliant_to_snake("this-is-a-test-label"))
# Output: this_is_a_test_label

# Input with invalid type
try:
    rfc1034_compliant_to_snake(12345)
except SmarterValueError as e:
    print(e)
# Output: Could not convert RFC 1034 compliant name from <class 'int'>
save()[source]

Save a plugin.

Returns:

True if the plugin was saved successfully, False otherwise.

Return type:

bool

Raises:

SmarterPluginError – If the plugin meta, selector, prompt, or data is not set or is not the correct instance.

selected(user, input_text=None, messages=None)[source]

Determine whether the plugin should be selected for a given user and input context.

This method evaluates plugin selection logic based on the plugin’s selector directive, search terms, and optionally provided input text or message history. It supports both direct text matching and message-based matching, using the plugin’s configured search terms.

Selection is performed as follows:

  • If the plugin selector directive is set to ALWAYS, the plugin is automatically selected.

  • If input_text is provided, the method checks if any search term matches the input using the NLP utility does_refer_to. If a match is found, the plugin is selected and a signal is sent.

  • If messages are provided, the method iterates through user messages and checks for matches against the search terms. If a match is found, the plugin is selected and a signal is sent.

Signals:

  • plugin_selected is sent when the plugin is selected via either input text or messages.

Parameters:
  • user (User) – The user for whom selection is being evaluated.

  • input_text (Optional[str]) – Optional input text to check for search term matches.

  • messages (Optional[list[dict]]) – Optional list of message dictionaries to check for search term matches.

Returns:

True if the plugin is selected, False otherwise.

Return type:

bool

Note

This method requires the plugin to be ready. If the plugin is not ready, it will return False. The method also updates the internal _selected state when a match is found.

smarter_build_absolute_uri(request)

Attempts to get the absolute URI from a request object.

This utility function tries to retrieve the request URL from any valid child class of django.http.HttpRequest. It is especially useful in unit tests or scenarios where the request object may not implement build_absolute_uri().

Parameters:

request (Optional[HttpRequest]) – The request object.

Returns:

The absolute request URL.

Return type:

Optional[str]

Raises:

SmarterValueError – If the URI cannot be built from the request.

snake_to_camel(data, convert_values=False)

Converts snake_case strings, dictionary keys, or lists of such, to camelCase format.

Parameters:
  • data (str, dict, or list) – The input to convert. Can be a string, a dictionary (with snake_case keys), or a list containing strings or dictionaries.

  • convert_values (bool, optional) – If True, string values within dictionaries are also converted to camelCase. Default is False.

Returns:

The converted data in camelCase format. Returns a string, dictionary, or list, matching the input type.

Return type:

Optional[Union[str, dict, list]]

Note

  • For dictionaries, only keys are converted by default. If convert_values is set, string values are also converted.

  • Nested dictionaries and lists are processed recursively.

Warning

If the input is not a string, dictionary, or list, a SmarterValueError is raised.

Example usage:

from smarter.common.utils import snake_to_camel

# Convert a string
print(snake_to_camel("user_name"))  # Output: userName

# Convert a dictionary
data = {
    "user_name": "alice",
    "user_profile": {
        "first_name": "Alice",
        "last_name": "Smith"
    }
}
print(snake_to_camel(data))
# Output: {'userName': 'alice', 'userProfile': {'firstName': 'Alice', 'lastName': 'Smith'}}

# Convert a list of strings
print(snake_to_camel(["first_name", "last_name"]))
# Output: ['firstName', 'lastName']

# Convert values as well
data = {"user_name": "first_name"}
print(snake_to_camel(data, convert_values=True))
# Output: {'userName': 'firstName'}
sorted_dict(data)

Returns a new dictionary with keys sorted.

Parameters:

data (dict) – The dictionary to sort.

Returns:

A new dictionary with sorted keys.

Return type:

dict

to_json(version='v1')[source]

Serialize the plugin as a JSON-compatible dictionary suitable for Pydantic import.

This method generates a manifest representation of the plugin, combining Django ORM model data and serializer output into a structured dictionary that matches the Smarter API schema. It is primarily used to render plugin manifests for API responses and for interoperability with Pydantic models.

The returned dictionary includes the following top-level keys:

  • apiVersion: The manifest API version.

  • kind: The manifest kind (plugin type).

  • metadata: Plugin metadata, serialized from the Django ORM.

  • spec: Specification section containing selector, prompt, and data.

  • status: Status information including IDs, account number, username, and timestamps.

The spec section is composed of:

  • selector: Serialized plugin selector.

  • prompt: Serialized plugin prompt.

  • data: Serialized plugin data.

The status section includes:

  • id: PluginMeta primary key.

  • accountNumber: Associated account number.

  • username: Username of the plugin owner.

  • created: ISO-formatted creation timestamp.

  • updated: ISO-formatted update timestamp.

Parameters:

version (str) – The manifest version to serialize. Only "v1" is supported.

Returns:

A dictionary representing the plugin manifest, or None if not ready.

Return type:

Optional[dict[str, Any]]

Raises:
  • SmarterConfigurationError – If serialization fails or the output is not a dictionary.

  • SmarterPluginError – If an unsupported version is requested.

Note

This method requires the plugin to be fully initialized and ready. All serializer properties must return valid data. If the plugin is not ready, None is returned.

abstractmethod tool_call_fetch_plugin_response(function_args)[source]

Fetch information from a Plugin object.

Parameters:

function_args (dict[str, Any]) – The function arguments from the OpenAI function call.

Returns:

The plugin response as a string.

Return type:

Optional[Union[dict, list, str]]

Raises:

NotImplementedError – If not implemented in a subclass.

property unformatted_class_name: str

Returns the raw class name without formatting.

Returns:

The unformatted class name as a string.

Return type:

str

This is useful for logging or serialization where the plain class name is needed.

update()[source]

Update a plugin.

Returns:

True if the plugin was updated successfully, False otherwise.

Return type:

bool

Raises:

SmarterPluginError – If the plugin manifest is not set or the plugin does not exist.

property user: AnonymousUser | User | None

Returns the user for the current user. Handle lazy instantiation from user_profile or account.

Returns:

The user for the current user.

Return type:

User or None

property user_profile: UserProfile | None

Returns the user_profile for the current user. Handle lazy instantiation from user or account.

Returns:

The user_profile for the current user.

Return type:

UserProfile or None

property yaml: str

Return the plugin as a yaml string.

Returns:

The plugin as a yaml string.

Return type:

str

Raises:

SmarterPluginError – If the plugin is not ready.

yaml_to_json(yaml_string)[source]

Convert a yaml string to a dictionary.

Parameters:

yaml_string (str) – The yaml string to convert.

Returns:

The converted dictionary.

Return type:

dict

Raises:

SmarterPluginError – If the yaml string is not valid.

exception smarter.apps.plugin.plugin.base.SmarterPluginError(message='')[source]

Bases: SmarterException

Base exception for Smarter API Plugin handling.

__init__(message='')
add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property get_formatted_err_message
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

smarter.apps.plugin.plugin.base.should_log(level)[source]

Check if logging should be done based on the waffle switch.