mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-02-12 15:05:10 -05:00
refactor: add NewVendorPluginBase factory function to reduce duplication
Add centralized factory function for AI vendor plugin initialization: - Add NewVendorPluginBase(name, configure) to internal/plugins/plugin.go - Update 8 vendor files (anthropic, bedrock, gemini, lmstudio, ollama, openai, perplexity, vertexai) to use the factory function - Add 3 test cases for the new factory function This removes ~40 lines of duplicated boilerplate code and ensures consistent plugin initialization across all vendors. MAESTRO: Loop 00001 refactoring implementation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,11 +29,7 @@ func NewClient() (ret *Client) {
|
||||
vendorName := "Anthropic"
|
||||
ret = &Client{}
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, ret.configure)
|
||||
|
||||
ret.ApiBaseURL = ret.AddSetupQuestion("API Base URL", false)
|
||||
ret.ApiBaseURL.Value = defaultBaseUrl
|
||||
|
||||
@@ -51,13 +51,9 @@ func NewClient() (ret *BedrockClient) {
|
||||
cfg, err := config.LoadDefaultConfig(ctx)
|
||||
if err != nil {
|
||||
// Create a minimal client that will fail gracefully during configuration
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: func() error {
|
||||
return fmt.Errorf("unable to load AWS Config: %w", err)
|
||||
},
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, func() error {
|
||||
return fmt.Errorf("unable to load AWS Config: %w", err)
|
||||
})
|
||||
ret.bedrockRegion = ret.PluginBase.AddSetupQuestion("AWS Region", true)
|
||||
return
|
||||
}
|
||||
@@ -67,11 +63,7 @@ func NewClient() (ret *BedrockClient) {
|
||||
runtimeClient := bedrockruntime.NewFromConfig(cfg)
|
||||
controlPlaneClient := bedrock.NewFromConfig(cfg)
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, ret.configure)
|
||||
|
||||
ret.runtimeClient = runtimeClient
|
||||
ret.controlPlaneClient = controlPlaneClient
|
||||
|
||||
@@ -46,10 +46,7 @@ func NewClient() (ret *Client) {
|
||||
vendorName := "Gemini"
|
||||
ret = &Client{}
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, nil)
|
||||
|
||||
ret.ApiKey = ret.PluginBase.AddSetupQuestion("API key", true)
|
||||
|
||||
|
||||
@@ -27,11 +27,7 @@ func NewClientCompatible(vendorName string, defaultBaseUrl string, configureCust
|
||||
if configureCustom == nil {
|
||||
configureCustom = ret.configure
|
||||
}
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: configureCustom,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, configureCustom)
|
||||
ret.ApiUrl = ret.AddSetupQuestionCustom("API URL", true,
|
||||
fmt.Sprintf("Enter your %v URL (as a reminder, it is usually %v')", vendorName, defaultBaseUrl))
|
||||
return
|
||||
|
||||
@@ -24,11 +24,7 @@ func NewClient() (ret *Client) {
|
||||
vendorName := "Ollama"
|
||||
ret = &Client{}
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, ret.configure)
|
||||
|
||||
ret.ApiUrl = ret.AddSetupQuestionCustom("API URL", true,
|
||||
"Enter your Ollama URL (as a reminder, it is usually http://localhost:11434')")
|
||||
|
||||
@@ -52,11 +52,7 @@ func NewClientCompatibleNoSetupQuestions(vendorName string, configureCustom func
|
||||
configureCustom = ret.configure
|
||||
}
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: configureCustom,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, configureCustom)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -31,11 +31,7 @@ type Client struct {
|
||||
|
||||
func NewClient() *Client {
|
||||
c := &Client{}
|
||||
c.PluginBase = &plugins.PluginBase{
|
||||
Name: providerName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(providerName),
|
||||
ConfigureCustom: c.Configure, // Assign the Configure method
|
||||
}
|
||||
c.PluginBase = plugins.NewVendorPluginBase(providerName, c.Configure)
|
||||
c.APIKey = c.AddSetupQuestion("API_KEY", true)
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -28,11 +28,7 @@ func NewClient() (ret *Client) {
|
||||
vendorName := "VertexAI"
|
||||
ret = &Client{}
|
||||
|
||||
ret.PluginBase = &plugins.PluginBase{
|
||||
Name: vendorName,
|
||||
EnvNamePrefix: plugins.BuildEnvVariablePrefix(vendorName),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
ret.PluginBase = plugins.NewVendorPluginBase(vendorName, ret.configure)
|
||||
|
||||
ret.ProjectID = ret.AddSetupQuestion("Project ID", true)
|
||||
ret.Region = ret.AddSetupQuestion("Region", false)
|
||||
|
||||
@@ -36,6 +36,16 @@ func (o *PluginBase) GetName() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// NewVendorPluginBase creates a standardized PluginBase for AI vendor plugins.
|
||||
// This centralizes the common initialization pattern used by all vendors.
|
||||
func NewVendorPluginBase(name string, configure func() error) *PluginBase {
|
||||
return &PluginBase{
|
||||
Name: name,
|
||||
EnvNamePrefix: BuildEnvVariablePrefix(name),
|
||||
ConfigureCustom: configure,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *PluginBase) GetSetupDescription() (ret string) {
|
||||
if ret = o.SetupDescription; ret == "" {
|
||||
ret = o.GetName()
|
||||
|
||||
@@ -8,6 +8,43 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewVendorPluginBase(t *testing.T) {
|
||||
// Test with configure function
|
||||
configureCalled := false
|
||||
configureFunc := func() error {
|
||||
configureCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
plugin := NewVendorPluginBase("TestVendor", configureFunc)
|
||||
|
||||
assert.Equal(t, "TestVendor", plugin.Name)
|
||||
assert.Equal(t, "TESTVENDOR_", plugin.EnvNamePrefix)
|
||||
assert.NotNil(t, plugin.ConfigureCustom)
|
||||
|
||||
// Test that configure function is properly stored
|
||||
err := plugin.ConfigureCustom()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, configureCalled)
|
||||
}
|
||||
|
||||
func TestNewVendorPluginBase_NilConfigure(t *testing.T) {
|
||||
// Test with nil configure function
|
||||
plugin := NewVendorPluginBase("TestVendor", nil)
|
||||
|
||||
assert.Equal(t, "TestVendor", plugin.Name)
|
||||
assert.Equal(t, "TESTVENDOR_", plugin.EnvNamePrefix)
|
||||
assert.Nil(t, plugin.ConfigureCustom)
|
||||
}
|
||||
|
||||
func TestNewVendorPluginBase_EnvPrefixWithSpaces(t *testing.T) {
|
||||
// Test that spaces are converted to underscores
|
||||
plugin := NewVendorPluginBase("LM Studio", nil)
|
||||
|
||||
assert.Equal(t, "LM Studio", plugin.Name)
|
||||
assert.Equal(t, "LM_STUDIO_", plugin.EnvNamePrefix)
|
||||
}
|
||||
|
||||
func TestConfigurable_AddSetting(t *testing.T) {
|
||||
conf := &PluginBase{
|
||||
Settings: Settings{},
|
||||
|
||||
Reference in New Issue
Block a user