SemanticPluginForge provides several advanced features that enable powerful customization scenarios.
This section covers the advanced capabilities of SemanticPluginForge:
Feature | Description | Use Cases |
---|---|---|
Function Suppression | Hide entire functions from plugin consumers | Deprecating functions, conditional availability |
Parameter Suppression | Hide specific parameters while providing defaults | Simplifying interfaces, context injection |
CLR Type Support | Use any .NET class as a plugin | Legacy code integration, external libraries |
Function Name Override | Change function names without code modification | Better naming conventions, API versioning |
Default Value Override | Set parameter defaults through metadata | Configuration-driven defaults, environment-specific values |
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
if (plugin.Name == "MyPlugin" && metadata.Name == "DeprecatedFunction")
{
return new FunctionMetadata(metadata.Name) { Suppress = true };
}
return null;
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
if (plugin.Name == "MyPlugin" && metadata.Name == "MyFunction")
{
return new FunctionMetadata(metadata.Name)
{
Parameters = new List<ParameterMetadata>
{
new ParameterMetadata("hiddenParam")
{
Suppress = true,
DefaultValue = "automatic"
}
}
};
}
return null;
}
public class DateUtility
{
public string GetCurrentDate() => DateTime.Now.ToShortDateString();
public string FormatDate(DateTime date) => date.ToString("yyyy-MM-dd");
}
// Register as plugin
kernelBuilder.Plugins.AddFromClrTypeWithMetadata<DateUtility>("DateUtils");
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
if (plugin.Name == "MyPlugin" && metadata.Name == "GetCurrentUsername")
{
return new FunctionMetadata(metadata.Name)
{
OverrideFunctionName = "GetUser"
};
}
return null;
}
Provide different metadata based on runtime conditions:
public class ConditionalMetadataProvider : IPluginMetadataProvider
{
private readonly IConfiguration _configuration;
public ConditionalMetadataProvider(IConfiguration configuration)
{
_configuration = configuration;
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
var isDebugMode = _configuration.GetValue<bool>("DebugMode");
if (plugin.Name == "AdminPlugin" && !isDebugMode)
{
// Suppress admin functions in production
return new FunctionMetadata(metadata.Name) { Suppress = true };
}
return null;
}
}
Combine metadata from multiple sources:
public class CompositeMetadataProvider : IPluginMetadataProvider
{
private readonly IEnumerable<IPluginMetadataProvider> _providers;
public CompositeMetadataProvider(IEnumerable<IPluginMetadataProvider> providers)
{
_providers = providers;
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
foreach (var provider in _providers)
{
var result = provider.GetFunctionMetadata(plugin, metadata);
if (result != null)
return result;
}
return null;
}
}
Load metadata from a database:
public class DatabaseMetadataProvider : IPluginMetadataProvider
{
private readonly IMetadataRepository _repository;
public DatabaseMetadataProvider(IMetadataRepository repository)
{
_repository = repository;
}
public async Task<FunctionMetadata?> GetFunctionMetadataAsync(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
var dbMetadata = await _repository.GetFunctionMetadataAsync(plugin.Name, metadata.Name);
if (dbMetadata == null) return null;
return new FunctionMetadata(metadata.Name)
{
Description = dbMetadata.Description,
Suppress = dbMetadata.IsHidden,
Parameters = dbMetadata.Parameters?.Select(p => new ParameterMetadata(p.Name)
{
Description = p.Description,
DefaultValue = p.DefaultValue,
Suppress = p.IsHidden
}).ToList()
};
}
}
For expensive metadata operations, consider caching:
public class CachedMetadataProvider : IPluginMetadataProvider
{
private readonly IMemoryCache _cache;
private readonly IPluginMetadataProvider _innerProvider;
public CachedMetadataProvider(IMemoryCache cache, IPluginMetadataProvider innerProvider)
{
_cache = cache;
_innerProvider = innerProvider;
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
var key = $"{plugin.Name}:{metadata.Name}";
return _cache.GetOrCreate(key, entry =>
{
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
return _innerProvider.GetFunctionMetadata(plugin, metadata);
});
}
}
For providers that need expensive initialization:
public class LazyMetadataProvider : IPluginMetadataProvider
{
private readonly Lazy<IExpensiveService> _expensiveService;
public LazyMetadataProvider()
{
_expensiveService = new Lazy<IExpensiveService>(() => new ExpensiveService());
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
// Service is only created when first needed
return _expensiveService.Value.GetMetadata(plugin.Name, metadata.Name);
}
}
Always provide fallbacks for metadata providers:
public class SafeMetadataProvider : IPluginMetadataProvider
{
private readonly IPluginMetadataProvider _innerProvider;
private readonly ILogger<SafeMetadataProvider> _logger;
public SafeMetadataProvider(IPluginMetadataProvider innerProvider, ILogger<SafeMetadataProvider> logger)
{
_innerProvider = innerProvider;
_logger = logger;
}
public FunctionMetadata? GetFunctionMetadata(KernelPlugin plugin, KernelFunctionMetadata metadata)
{
try
{
return _innerProvider.GetFunctionMetadata(plugin, metadata);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting metadata for {PluginName}.{FunctionName}", plugin.Name, metadata.Name);
return null; // Fall back to original metadata
}
}
}