calute.extensions.plugins#
Plugin system for Calute.
Supports four plugin types:
tool: Provides callable tool functions for agents.
hook: Provides lifecycle hooks (before/after tool, bootstrap, etc.).
provider: Provides LLM provider implementations.
channel: (Future) Provides communication channel integrations.
Plugins are Python modules or classes that register themselves with the
PluginRegistry. Local plugin discovery scans a configured directory for
modules containing a register(registry) function.
Example plugin module (my_plugin.py):
from calute.extensions.plugins import PluginMeta, PluginType
PLUGIN_META = PluginMeta(
name="my_plugin",
version="1.0.0",
plugin_type=PluginType.TOOL,
description="My custom tools",
)
def my_tool(query: str) -> str:
'''Search for something.'''
return f"Results for {query}"
def register(registry):
registry.register_tool("my_tool", my_tool, meta=PLUGIN_META)
- exception calute.extensions.plugins.PluginConflictError(name: str, existing: str)[source]#
Bases:
ExceptionRaised when a plugin or resource name conflicts with an existing registration.
- name#
The name of the plugin or resource that caused the conflict.
- existing#
The name of the already-registered plugin that owns the conflicting resource.
- class calute.extensions.plugins.PluginMeta(name: str, version: str = '0.1.0', plugin_type: ~calute.extensions.plugins.PluginType = PluginType.TOOL, description: str = '', author: str = '', dependencies: list[str] = <factory>, version_constraints: dict[str, str] = <factory>)[source]#
Bases:
objectMetadata describing a Calute plugin.
Every plugin must provide a
PluginMetainstance when it registers itself. The metadata is used for dependency resolution, conflict detection, and informational logging.- name#
A unique identifier for the plugin (e.g.,
"my_search_plugin").- Type
str
- version#
A semver-style version string for the plugin (default
"0.1.0").- Type
str
- plugin_type#
The category of functionality the plugin provides.
- description#
A short human-readable description of the plugin.
- Type
str
- author#
The name or handle of the plugin author.
- Type
str
- dependencies#
A list of dependency strings (plugin names, optionally with version constraints like
"other_plugin>=1.0").- Type
list[str]
- version_constraints#
A mapping of plugin names to version constraint expressions (e.g.,
{"core": ">=2.0,<3.0"}). These are checked in addition to dependencies.- Type
dict[str, str]
- author: str = ''#
- dependencies: list[str]#
- description: str = ''#
- name: str#
- plugin_type: PluginType = 'tool'#
- version: str = '0.1.0'#
- version_constraints: dict[str, str]#
- class calute.extensions.plugins.PluginRegistry[source]#
Bases:
objectCentral registry for plugin management, discovery, and dependency validation.
Plugins register tools, hooks, and providers through this registry. The registry tracks ownership so that all resources belonging to a plugin can be removed atomically via
unregister_plugin().- _plugins#
Internal mapping of plugin name to
RegisteredPlugin.
- _tools#
Mapping of tool name to
(callable, plugin_name)tuple.
- _hooks#
Mapping of hook name to list of
(callable, plugin_name)tuples, in registration order.
- _providers#
Mapping of provider name to
(provider, plugin_name)tuple.
Example
>>> registry = PluginRegistry() >>> registry.register_tool("my_tool", my_func, meta=PluginMeta(name="test")) >>> func = registry.get_tool("my_tool")
- discover(directory: str | pathlib.Path) list[str][source]#
Discover and load plugins from a directory.
Scans the given directory for top-level Python files (ignoring those starting with
_). Each file is loaded as a temporary module; if it exposes aregister(registry)function, that function is called with self to let the plugin register its resources.Modules are removed from
sys.modulesafter loading to avoid polluting the global namespace.- Parameters
directory – Path to the directory to scan for plugin modules.
- Returns
A list of plugin names that were newly registered during discovery.
- get_all_tools() dict[str, Callable][source]#
Return a mapping of tool name to callable for all registered tools.
- Returns
A dictionary mapping each tool name to its callable implementation. The result is a new dict; mutating it does not affect the registry.
- get_hooks(hook_name: str) list[Callable][source]#
Get all registered hook callbacks for a hook point.
- Parameters
hook_name – The hook point name to query.
- Returns
A list of callable hooks in registration order. Returns an empty list if no hooks are registered for the given name.
- get_load_order() list[str][source]#
Return plugin names in dependency-safe order (dependencies first).
- Raises
calute.extensions.dependency.CircularDependencyError – If circular deps exist.
- get_plugin(name: str) calute.extensions.plugins.RegisteredPlugin | None[source]#
Look up a registered plugin by name.
- Parameters
name – The plugin name to look up.
- Returns
The
RegisteredPlugininstance, orNoneif no plugin with the given name exists.
- get_provider(provider_name: str) Any | None[source]#
Look up a registered LLM provider by name.
- Parameters
provider_name – The name the provider was registered under.
- Returns
The provider instance, or
Noneif not found.
- get_tool(tool_name: str) Optional[Callable][source]#
Look up a registered tool by name.
- Parameters
tool_name – The name the tool was registered under.
- Returns
The callable tool function, or
Noneif no tool with the given name is registered.
- property plugin_names: list[str]#
Return the names of all registered plugins.
- Returns
A list of plugin name strings in insertion order.
- register_hook(hook_name: str, func: Callable, meta: calute.extensions.plugins.PluginMeta | None = None, plugin_name: str | None = None) None[source]#
Register a hook callback function.
Multiple hooks can be registered for the same hook point; they are stored in registration order. If meta is provided and the owning plugin is not yet registered, it is auto-registered first.
- Parameters
hook_name – The hook point name (e.g.,
"before_tool_call").func – The callable to invoke at this hook point.
meta – Optional plugin metadata. If provided and the plugin is not yet registered,
register_plugin()is called automatically.plugin_name – Explicit plugin name override. If omitted, the name is inferred from meta or defaults to
"__standalone__".
- register_plugin(meta: PluginMeta) RegisteredPlugin[source]#
Register a plugin by its metadata.
Creates a new
RegisteredPluginentry and stores it in the internal registry. Duplicate names are not allowed.- Parameters
meta – The
PluginMetadescribing the plugin.- Returns
The newly created
RegisteredPluginhandle.- Raises
PluginConflictError – If a plugin with the same name is already registered.
- register_provider(provider_name: str, provider: Any, meta: calute.extensions.plugins.PluginMeta | None = None, plugin_name: str | None = None) None[source]#
Register an LLM provider implementation.
Only one provider can be registered per provider_name. If meta is provided and the owning plugin is not yet registered, it is auto-registered first.
- Parameters
provider_name – A unique name for the provider (e.g.,
"openai").provider – The provider instance or factory.
meta – Optional plugin metadata for auto-registration.
plugin_name – Explicit plugin name override.
- Raises
PluginConflictError – If a provider with the same name is already registered.
- register_tool(tool_name: str, func: Callable, meta: calute.extensions.plugins.PluginMeta | None = None, plugin_name: str | None = None) None[source]#
Register a tool function.
- Parameters
tool_name – Name for the tool (used for policy checks and LLM schema).
func – The callable tool function.
meta – Optional plugin metadata (auto-registers plugin if not already).
plugin_name – Name of the owning plugin (inferred from meta if provided).
- class calute.extensions.plugins.PluginType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#
Bases:
EnumEnumeration of plugin categories supported by the Calute plugin system.
Each plugin declares its type via
PluginMeta, and thePluginRegistryuses the type to route registrations to the correct internal storage.- TOOL#
Provides callable tool functions for agents.
- HOOK#
Provides lifecycle hooks (before/after tool, bootstrap, etc.).
- PROVIDER#
Provides LLM provider implementations.
- CHANNEL#
Communication channel integrations (reserved for future use).
- SEARCH#
Search-engine integrations.
- SPEECH#
Speech/TTS integrations.
- CHANNEL = 'channel'#
- HOOK = 'hook'#
- PROVIDER = 'provider'#
- SEARCH = 'search'#
- SPEECH = 'speech'#
- TOOL = 'tool'#
- class calute.extensions.plugins.RegisteredPlugin(meta: ~calute.extensions.plugins.PluginMeta, tools: dict[str, typing.Callable] = <factory>, hooks: dict[str, typing.Callable] = <factory>, provider: ~typing.Any = None)[source]#
Bases:
objectA plugin that has been registered with the
PluginRegistry.Aggregates the plugin metadata together with the tools, hooks, and provider that the plugin contributed during registration.
- meta#
The metadata describing the plugin.
- tools#
A mapping of tool names to their callable implementations registered by this plugin.
- Type
dict[str, Callable]
- hooks#
A mapping of hook point names to their callable implementations registered by this plugin.
- Type
dict[str, Callable]
- provider#
An optional LLM provider instance registered by this plugin.
Noneif the plugin does not provide a provider.- Type
Any
- hooks: dict[str, Callable]#
- meta: PluginMeta#
- provider: Any = None#
- tools: dict[str, Callable]#