Skip to content

Python: Verify that plugin names are unique. #6433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions python/semantic_kernel/functions/kernel_function_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pydantic import Field, field_validator

from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.exceptions import KernelFunctionNotFoundError, KernelPluginNotFoundError
from semantic_kernel.exceptions import KernelFunctionNotFoundError, KernelPluginNotFoundError, PluginInvalidNameError
from semantic_kernel.functions.kernel_function_metadata import KernelFunctionMetadata
from semantic_kernel.functions.kernel_plugin import KernelPlugin
from semantic_kernel.kernel_pydantic import KernelBaseModel
Expand Down Expand Up @@ -81,24 +81,28 @@ def add_plugin(
ValidationError: If a KernelPlugin needs to be created, but it is not valid.

"""
name = plugin.name if isinstance(plugin, KernelPlugin) else plugin_name

if name in self.plugins:
raise PluginInvalidNameError(f"A plugin with the name {name} already exists.")
if isinstance(plugin, KernelPlugin):
self.plugins[plugin.name] = plugin
return self.plugins[plugin.name]
if not plugin_name:
raise ValueError("plugin_name must be provided if a plugin is not supplied.")
self.plugins[name] = plugin
return self.plugins[name]
if not name:
raise PluginInvalidNameError("plugin_name must be provided if a plugin is not supplied.")
if plugin:
self.plugins[plugin_name] = KernelPlugin.from_object(
plugin_name=plugin_name, plugin_instance=plugin, description=description
self.plugins[name] = KernelPlugin.from_object(
plugin_name=name, plugin_instance=plugin, description=description
)
return self.plugins[plugin_name]
return self.plugins[name]
if plugin is None and parent_directory is not None:
self.plugins[plugin_name] = KernelPlugin.from_directory(
plugin_name=plugin_name,
self.plugins[name] = KernelPlugin.from_directory(
plugin_name=name,
parent_directory=parent_directory,
description=description,
class_init_arguments=class_init_arguments,
)
return self.plugins[plugin_name]
return self.plugins[name]
raise ValueError("plugin or parent_directory must be provided.")

def add_plugins(self, plugins: list[KernelPlugin] | dict[str, KernelPlugin | object]) -> None:
Expand Down
10 changes: 9 additions & 1 deletion python/tests/unit/kernel/test_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from semantic_kernel.exceptions import (
KernelFunctionAlreadyExistsError,
KernelServiceNotFoundError,
PluginInvalidNameError,
ServiceInvalidTypeError,
)
from semantic_kernel.exceptions.kernel_exceptions import KernelFunctionNotFoundError, KernelPluginNotFoundError
Expand Down Expand Up @@ -185,7 +186,7 @@ def test_plugin_no_plugin(kernel: Kernel):


def test_plugin_name_error(kernel: Kernel):
with pytest.raises(ValueError):
with pytest.raises(PluginInvalidNameError, match="plugin_name must be provided if a plugin is not supplied."):
kernel.add_plugin(" ", None)


Expand All @@ -197,6 +198,13 @@ def test_plugins_add_plugins(kernel: Kernel):
assert len(kernel.plugins) == 2


def test_plugins_name_unique(kernel: Kernel):
with pytest.raises(PluginInvalidNameError, match="A plugin with the name TestPlugin already exists."):
plugin1 = KernelPlugin(name="TestPlugin")
plugin2 = KernelPlugin(name="TestPlugin")
kernel.add_plugins([plugin1, plugin2])


def test_add_function_from_prompt(kernel: Kernel):
prompt = """
Write a short story about two Corgis on an adventure.
Expand Down
Loading