mirror of
https://github.com/langgenius/dify-plugin-daemon.git
synced 2026-07-22 17:56:00 -04:00
4589841b0c
* feat(plugins): add FetchPluginReadme endpoint and update launch configurations * feat: add PluginReadme database model * feat: implement readme extracting and storage * feat: implement readme endpoint * feat: add plugin asset extraction endpoint with caching support * Implement trigger functionality and clean up dynamic select code - Added new trigger-related access types and actions in access.go. - Introduced new HTTP routes for trigger operations in http_server.gen.go. - Updated plugin declaration to include triggers in plugin_entities. - Removed unused dynamic select service and controller files. - Enhanced message handling in debugging_runtime to support trigger registration. This update enhances the plugin system by integrating trigger capabilities while cleaning up legacy code. * Refactor trigger-related types and enhance dynamic select functionality - Updated TriggerProviderIdentity and TriggerProviderConfiguration to improve structure and validation. - Renamed TriggerConfiguration to TriggerDeclaration for clarity. - Added CredentialType to RequestDynamicParameterSelect for better request handling. - Enhanced PluginDecoderHelper to read and unmarshal trigger files correctly. These changes streamline the trigger system and improve the overall request handling in the plugin architecture. * Add trigger functionality and enhance database integration - Introduced TriggerInstallation model for managing trigger installations in the database. - Updated autoMigrate function to include trigger installations in the migration process. - Added new HTTP routes for listing and retrieving triggers in the HTTP server. - Implemented ListTriggers and GetTrigger controller functions for handling trigger requests. - Enhanced plugin management functions to create, update, and delete trigger installations during plugin lifecycle events. These changes integrate trigger capabilities into the system, improving the overall plugin functionality and management. * feat: add remapping for trigger icons in MediaBucket - Enhanced the RemapAssets function to include remapping of trigger identity icons and dark icons. - Added error handling for remapping failures to ensure robust asset management. These changes improve the handling of trigger assets within the plugin system, ensuring icons are correctly remapped as needed. * feat: add Multiple field to TriggerParameter for enhanced configuration - Introduced a new Multiple field in the TriggerParameter struct to allow for multiple values in trigger configurations. - This addition improves the flexibility of trigger parameters within the plugin system. These changes enhance the capability of trigger parameters, enabling more complex configurations. * feat: add Multiple field to ProviderConfig for enhanced configuration - Introduced a new Multiple field in the ProviderConfig struct to allow for multiple values in provider configurations. - This addition improves the flexibility of provider options within the plugin system. These changes enhance the capability of provider configurations, enabling more complex setups. * fix(plugin): update validation error messages in ManifestValidate method - Enhanced error messages in the ManifestValidate function to include 'trigger' in the validation checks for plugin declarations. - Updated logic to ensure that all relevant fields are considered when validating the presence of mutually exclusive parameters. * feat(trigger): add CHECKBOX parameter type to plugin entities and refactor the trigger provider strcuture - Introduced a new CHECKBOX parameter type in constant.go for plugin entities. - Updated tool_declaration.go and trigger_declaration.go to include TOOL_PARAMETER_TYPE_CHECKBOX and TRIGGER_PARAMETER_TYPE_CHECKBOX respectively. - Enhanced validation logic to accommodate the new CHECKBOX type in parameter checks. * fix(trigger): update SubscriptionSchema validation in TriggerProviderDeclaration - Changed SubscriptionSchema validation from 'omitempty' to 'required' in TriggerProviderDeclaration to ensure it is always provided. - Updated SubscriptionConstructor field to be a pointer to allow for optional inclusion in the trigger provider configuration. * fix(trigger): rename ParametersSchema to Parameters in SubscriptionConstructor - Updated the SubscriptionConstructor struct to rename the ParametersSchema field to Parameters for consistency. - Adjusted related JSON and YAML marshaling logic to reflect the new field name, ensuring proper handling of trigger parameters. * refactor(trigger): enhance YAML unmarshalling for SubscriptionConstructor and SubscriptionSchema - Introduced a new helper function to convert YAML nodes to ProviderConfig lists, improving the handling of subscription_schema and credentials_schema. - Updated the UnmarshalYAML method to utilize the new function, simplifying the logic for parsing different YAML formats. - Ensured proper initialization of SubscriptionConstructor fields to prevent nil pointer dereferences. * fix(trigger): update SubscriptionConstructor validation in TriggerProviderDeclaration - Changed the validation for SubscriptionConstructor in TriggerProviderDeclaration from 'omitempty,dive' to 'omitempty' to simplify the validation logic. - Ensured that the SubscriptionConstructor field remains optional while maintaining its intended functionality. * refactor(trigger): rename Trigger to Event in plugin entities and related structures - Updated the naming conventions in trigger_declaration.go to replace 'Trigger' with 'Event' for better clarity and consistency. - Adjusted related types, validation functions, and unmarshalling logic to reflect the new 'Event' terminology. - Ensured that all references to triggers in the codebase are updated to events, including in the SubscriptionConstructor and response structures. * refactor(trigger): rename TriggerInvoke to TriggerInvokeEvent and update related structures - Renamed TriggerInvoke function and associated request/response types to TriggerInvokeEvent for improved clarity. - Updated routing and controller methods to reflect the new naming convention. - Ensured all references to the trigger invoke functionality are consistent with the new event terminology. * refactor(trigger): remove Subscription struct from trigger_declaration.go and update TriggerDispatchEventRequest - Removed the Subscription struct from trigger_declaration.go to streamline the codebase. - Added Credentials field to TriggerDispatchEventRequest for enhanced functionality and clarity. - Ensured that the changes maintain consistency with the existing naming conventions and structures. * fix(trigger): improve nil checks for SubscriptionConstructor in TriggerProviderDeclaration - Added nil checks for SubscriptionConstructor before accessing its fields to prevent potential nil pointer dereferences. - Ensured that Parameters and CredentialsSchema are initialized only if SubscriptionConstructor is not nil, enhancing code robustness. * fix(plugin): add recovery mechanism in OnTraffic to handle panics - Introduced a deferred function in OnTraffic to recover from panics, logging the error and stack trace for better debugging. - This enhancement improves the stability of the DifyServer by preventing crashes due to unexpected runtime errors. * feat(trigger): add Subscription field to TriggerInvokeEventRequest - Introduced a new Subscription field in the TriggerInvokeEventRequest struct to accommodate subscription data. - Ensured the field is marked as required, enhancing the request's functionality and validation requirements. * refactor(event): simplify EventDescription structure in EventDeclaration - Removed the EventDescription struct and replaced it with a direct I18nObject field in EventDeclaration. - This change streamlines the event configuration by reducing complexity while maintaining required validation for the description. * feat(trigger): add UserID field to TriggerDispatchEventResponse - Introduced a new UserID field in the TriggerDispatchEventResponse struct to include user identification in the response. - The field is marked as optional, enhancing the response's flexibility while maintaining existing functionality. * feat: add payload to TriggerDispatchEventResponse * fix * feat(trigger): update TriggerDispatchEventResponse structure * fix: avoid path collusion * fix: missing ) * fix: query param * fix: form param * fix: remove redundant dynamic parameter access type * fix: remove dynamic parameter access type from validation * Update internal/server/controllers/plugins.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: Stream <Stream_2@qq.com> Co-authored-by: Yeuoly <admin@srmxy.cn> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
445 lines
14 KiB
Go
445 lines
14 KiB
Go
package plugin_entities
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/go-playground/locales/en"
|
|
ut "github.com/go-playground/universal-translator"
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/langgenius/dify-plugin-daemon/pkg/validators"
|
|
)
|
|
|
|
type ConfigType string
|
|
|
|
const (
|
|
CONFIG_TYPE_SECRET_INPUT ConfigType = SECRET_INPUT
|
|
CONFIG_TYPE_TEXT_INPUT ConfigType = TEXT_INPUT
|
|
CONFIG_TYPE_SELECT ConfigType = SELECT
|
|
CONFIG_TYPE_BOOLEAN ConfigType = BOOLEAN
|
|
CONFIG_TYPE_MODEL_SELECTOR ConfigType = MODEL_SELECTOR
|
|
CONFIG_TYPE_APP_SELECTOR ConfigType = APP_SELECTOR
|
|
// CONFIG_TYPE_TOOL_SELECTOR ConfigType = TOOL_SELECTOR
|
|
CONFIG_TYPE_TOOLS_SELECTOR ConfigType = TOOLS_SELECTOR
|
|
CONFIG_TYPE_ANY ConfigType = ANY
|
|
)
|
|
|
|
type ModelConfigScope string
|
|
|
|
const (
|
|
MODEL_CONFIG_SCOPE_ALL ModelConfigScope = "all"
|
|
MODEL_CONFIG_SCOPE_LLM ModelConfigScope = "llm"
|
|
MODEL_CONFIG_SCOPE_TEXT_EMBEDDING ModelConfigScope = "text-embedding"
|
|
MODEL_CONFIG_SCOPE_RERANK ModelConfigScope = "rerank"
|
|
MODEL_CONFIG_SCOPE_TTS ModelConfigScope = "tts"
|
|
MODEL_CONFIG_SCOPE_SPEECH2TEXT ModelConfigScope = "speech2text"
|
|
MODEL_CONFIG_SCOPE_MODERATION ModelConfigScope = "moderation"
|
|
MODEL_CONFIG_SCOPE_VISION ModelConfigScope = "vision"
|
|
MODEL_CONFIG_SCOPE_DOCUMENT ModelConfigScope = "document"
|
|
MODEL_CONFIG_SCOPE_TOOL_CALL ModelConfigScope = "tool-call"
|
|
)
|
|
|
|
type AppSelectorScope string
|
|
|
|
const (
|
|
APP_SELECTOR_SCOPE_ALL AppSelectorScope = "all"
|
|
APP_SELECTOR_SCOPE_CHAT AppSelectorScope = "chat"
|
|
APP_SELECTOR_SCOPE_WORKFLOW AppSelectorScope = "workflow"
|
|
APP_SELECTOR_SCOPE_COMPLETION AppSelectorScope = "completion"
|
|
)
|
|
|
|
type ToolSelectorScope string
|
|
|
|
const (
|
|
TOOL_SELECTOR_SCOPE_ALL ToolSelectorScope = "all"
|
|
TOOL_SELECTOR_SCOPE_PLUGIN ToolSelectorScope = "plugin"
|
|
TOOL_SELECTOR_SCOPE_API ToolSelectorScope = "api"
|
|
TOOL_SELECTOR_SCOPE_WORKFLOW ToolSelectorScope = "workflow"
|
|
)
|
|
|
|
type AnyScope string
|
|
|
|
const (
|
|
ANY_SCOPE_STRING AnyScope = "string"
|
|
ANY_SCOPE_NUMBER AnyScope = "number"
|
|
ANY_SCOPE_OBJECT AnyScope = "object"
|
|
ANY_SCOPE_ARRAY_NUMBER AnyScope = "array[number]"
|
|
ANY_SCOPE_ARRAY_STRING AnyScope = "array[string]"
|
|
ANY_SCOPE_ARRAY_OBJECT AnyScope = "array[object]"
|
|
ANY_SCOPE_ARRAY_FILES AnyScope = "array[file]"
|
|
)
|
|
|
|
func isCredentialType(fl validator.FieldLevel) bool {
|
|
value := fl.Field().String()
|
|
switch value {
|
|
case string(CONFIG_TYPE_SECRET_INPUT),
|
|
string(CONFIG_TYPE_TEXT_INPUT),
|
|
string(CONFIG_TYPE_SELECT),
|
|
string(CONFIG_TYPE_BOOLEAN),
|
|
string(CONFIG_TYPE_APP_SELECTOR),
|
|
string(CONFIG_TYPE_MODEL_SELECTOR),
|
|
string(CONFIG_TYPE_TOOLS_SELECTOR):
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
type ConfigOption struct {
|
|
Value string `json:"value" validate:"required,lt=128"`
|
|
Label I18nObject `json:"label" validate:"required"`
|
|
}
|
|
|
|
func isModelConfigScope(fl validator.FieldLevel) bool {
|
|
value := fl.Field().String()
|
|
// split by and symbol
|
|
scopes := strings.Split(value, "&")
|
|
for _, scope := range scopes {
|
|
// trim space
|
|
scope = strings.TrimSpace(scope)
|
|
switch scope {
|
|
case string(MODEL_CONFIG_SCOPE_LLM),
|
|
string(MODEL_CONFIG_SCOPE_TEXT_EMBEDDING),
|
|
string(MODEL_CONFIG_SCOPE_RERANK),
|
|
string(MODEL_CONFIG_SCOPE_TTS),
|
|
string(MODEL_CONFIG_SCOPE_SPEECH2TEXT),
|
|
string(MODEL_CONFIG_SCOPE_MODERATION),
|
|
string(MODEL_CONFIG_SCOPE_VISION),
|
|
string(MODEL_CONFIG_SCOPE_DOCUMENT),
|
|
string(MODEL_CONFIG_SCOPE_TOOL_CALL):
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isAppSelectorScope(fl validator.FieldLevel) bool {
|
|
value := fl.Field().String()
|
|
// split by and symbol
|
|
scopes := strings.Split(value, "&")
|
|
for _, scope := range scopes {
|
|
// trim space
|
|
scope = strings.TrimSpace(scope)
|
|
switch scope {
|
|
case string(APP_SELECTOR_SCOPE_ALL),
|
|
string(APP_SELECTOR_SCOPE_CHAT),
|
|
string(APP_SELECTOR_SCOPE_WORKFLOW),
|
|
string(APP_SELECTOR_SCOPE_COMPLETION):
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isToolSelectorScope(fl validator.FieldLevel) bool {
|
|
value := fl.Field().String()
|
|
// split by and symbol
|
|
scopes := strings.Split(value, "&")
|
|
for _, scope := range scopes {
|
|
// trim space
|
|
scope = strings.TrimSpace(scope)
|
|
switch scope {
|
|
case string(TOOL_SELECTOR_SCOPE_ALL),
|
|
string(TOOL_SELECTOR_SCOPE_PLUGIN),
|
|
string(TOOL_SELECTOR_SCOPE_API),
|
|
string(TOOL_SELECTOR_SCOPE_WORKFLOW):
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isVarSelectorScope(fl validator.FieldLevel) bool {
|
|
value := fl.Field().String()
|
|
// split by and symbol
|
|
scopes := strings.Split(value, "&")
|
|
for _, scope := range scopes {
|
|
// trim space
|
|
scope = strings.TrimSpace(scope)
|
|
switch scope {
|
|
case string(ANY_SCOPE_STRING),
|
|
string(ANY_SCOPE_NUMBER),
|
|
string(ANY_SCOPE_OBJECT),
|
|
string(ANY_SCOPE_ARRAY_NUMBER),
|
|
string(ANY_SCOPE_ARRAY_STRING),
|
|
string(ANY_SCOPE_ARRAY_OBJECT),
|
|
string(ANY_SCOPE_ARRAY_FILES):
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isScope(fl validator.FieldLevel) bool {
|
|
// get parent and check if it's a provider config
|
|
parent := fl.Parent().Interface()
|
|
if providerConfig, ok := parent.(ProviderConfig); ok {
|
|
// check config type
|
|
if providerConfig.Type == CONFIG_TYPE_APP_SELECTOR {
|
|
return isAppSelectorScope(fl)
|
|
} else if providerConfig.Type == CONFIG_TYPE_MODEL_SELECTOR {
|
|
return isModelConfigScope(fl)
|
|
} else if providerConfig.Type == CONFIG_TYPE_ANY {
|
|
return isVarSelectorScope(fl)
|
|
} else {
|
|
return false
|
|
}
|
|
|
|
//else if providerConfig.Type == CONFIG_TYPE_TOOL_SELECTOR {
|
|
//return isToolSelectorScope(fl)
|
|
//}
|
|
}
|
|
if toolParameter, ok := parent.(ToolParameter); ok {
|
|
if toolParameter.Type == TOOL_PARAMETER_TYPE_APP_SELECTOR {
|
|
return isAppSelectorScope(fl)
|
|
} else if toolParameter.Type == TOOL_PARAMETER_TYPE_MODEL_SELECTOR {
|
|
return isModelConfigScope(fl)
|
|
} else if toolParameter.Type == TOOL_PARAMETER_TYPE_ANY {
|
|
return isVarSelectorScope(fl)
|
|
} else {
|
|
return false
|
|
}
|
|
|
|
// else if toolParameter.Type == TOOL_PARAMETER_TYPE_TOOL_SELECTOR {
|
|
// return isToolSelectorScope(fl)
|
|
// }
|
|
}
|
|
|
|
if agentStrategyParameter, ok := parent.(AgentStrategyParameter); ok {
|
|
if agentStrategyParameter.Type == AGENT_STRATEGY_PARAMETER_TYPE_APP_SELECTOR {
|
|
return isAppSelectorScope(fl)
|
|
} else if agentStrategyParameter.Type == AGENT_STRATEGY_PARAMETER_TYPE_MODEL_SELECTOR {
|
|
return isModelConfigScope(fl)
|
|
} else if agentStrategyParameter.Type == AGENT_STRATEGY_PARAMETER_TYPE_ANY {
|
|
return isVarSelectorScope(fl)
|
|
} else {
|
|
return false
|
|
}
|
|
|
|
//else if agentStrategyParameter.Type == AGENT_STRATEGY_PARAMETER_TYPE_TOOLS_SELECTOR {
|
|
// return isToolSelectorScope(fl)
|
|
//}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func init() {
|
|
en := en.New()
|
|
uni := ut.New(en, en)
|
|
translator, _ := uni.GetTranslator("en")
|
|
|
|
validators.GlobalEntitiesValidator.RegisterValidation("is_scope", isScope)
|
|
validators.GlobalEntitiesValidator.RegisterTranslation(
|
|
"is_scope",
|
|
translator,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add("is_scope", "{0} is not a valid scope", true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
t, _ := ut.T("is_scope", fe.Field())
|
|
return t
|
|
},
|
|
)
|
|
|
|
validators.GlobalEntitiesValidator.RegisterValidation("is_app_selector_scope", isAppSelectorScope)
|
|
validators.GlobalEntitiesValidator.RegisterTranslation(
|
|
"is_app_selector_scope",
|
|
translator,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add("is_app_selector_scope", "{0} is not a valid app selector scope", true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
t, _ := ut.T("is_app_selector_scope", fe.Field())
|
|
return t
|
|
},
|
|
)
|
|
|
|
validators.GlobalEntitiesValidator.RegisterValidation("is_model_config_scope", isModelConfigScope)
|
|
validators.GlobalEntitiesValidator.RegisterTranslation(
|
|
"is_model_config_scope",
|
|
translator,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add("is_model_config_scope", "{0} is not a valid model config scope", true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
t, _ := ut.T("is_model_config_scope", fe.Field())
|
|
return t
|
|
},
|
|
)
|
|
|
|
validators.GlobalEntitiesValidator.RegisterValidation("is_tool_selector_scope", isToolSelectorScope)
|
|
validators.GlobalEntitiesValidator.RegisterTranslation(
|
|
"is_tool_selector_scope",
|
|
translator,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add("is_tool_selector_scope", "{0} is not a valid tool selector scope", true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
t, _ := ut.T("is_tool_selector_scope", fe.Field())
|
|
return t
|
|
},
|
|
)
|
|
}
|
|
|
|
type ProviderConfig struct {
|
|
Name string `json:"name" validate:"omitempty,gt=0,lt=1024"`
|
|
Type ConfigType `json:"type" validate:"required,credential_type"`
|
|
Scope *string `json:"scope" validate:"omitempty,is_scope"`
|
|
Required bool `json:"required"`
|
|
Default any `json:"default" validate:"omitempty,is_basic_type"`
|
|
Options []ConfigOption `json:"options" validate:"omitempty,lt=128,dive"`
|
|
Multiple bool `json:"multiple" validate:"omitempty"`
|
|
Label I18nObject `json:"label" validate:"required"`
|
|
Help *I18nObject `json:"help" validate:"omitempty"`
|
|
URL *string `json:"url" validate:"omitempty"`
|
|
Placeholder *I18nObject `json:"placeholder" validate:"omitempty"`
|
|
}
|
|
|
|
func init() {
|
|
en := en.New()
|
|
uni := ut.New(en, en)
|
|
translator, _ := uni.GetTranslator("en")
|
|
|
|
validators.GlobalEntitiesValidator.RegisterValidation("credential_type", isCredentialType)
|
|
validators.GlobalEntitiesValidator.RegisterTranslation(
|
|
"credential_type",
|
|
translator,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add("credential_type", "{0} is not a valid credential type", true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
t, _ := ut.T("credential_type", fe.Field())
|
|
return t
|
|
},
|
|
)
|
|
}
|
|
|
|
// ValidateProviderConfigs validates the provider configs
|
|
func ValidateProviderConfigs(settings map[string]any, configs []ProviderConfig) error {
|
|
if len(settings) > 64 {
|
|
return errors.New("too many setting fields")
|
|
}
|
|
|
|
configsMap := make(map[string]ProviderConfig)
|
|
for _, config := range configs {
|
|
configsMap[config.Name] = config
|
|
}
|
|
|
|
for config_name, config := range configsMap {
|
|
v, ok := settings[config_name]
|
|
if (!ok || v == nil) && config.Required {
|
|
return errors.New("missing required setting: " + config_name)
|
|
}
|
|
|
|
if !ok || v == nil {
|
|
continue
|
|
}
|
|
|
|
// check type
|
|
switch config.Type {
|
|
case CONFIG_TYPE_TEXT_INPUT:
|
|
if _, ok := v.(string); !ok {
|
|
return errors.New("setting " + config_name + " is not a string")
|
|
}
|
|
case CONFIG_TYPE_SECRET_INPUT:
|
|
if _, ok := v.(string); !ok {
|
|
return errors.New("setting " + config_name + " is not a string")
|
|
}
|
|
case CONFIG_TYPE_SELECT:
|
|
if _, ok := v.(string); !ok {
|
|
return errors.New("setting " + config_name + " is not a string")
|
|
}
|
|
// check if value is in options
|
|
found := false
|
|
for _, option := range config.Options {
|
|
if v == option.Value {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return errors.New("setting " + config_name + " is not a valid option")
|
|
}
|
|
case CONFIG_TYPE_BOOLEAN:
|
|
if _, ok := v.(bool); !ok {
|
|
return errors.New("setting " + config_name + " is not a boolean")
|
|
}
|
|
case CONFIG_TYPE_APP_SELECTOR:
|
|
m, ok := v.(map[string]any)
|
|
if !ok {
|
|
return errors.New("setting " + config_name + " is not a map")
|
|
}
|
|
// check keys
|
|
if _, ok := m["app_id"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing app_id")
|
|
}
|
|
case CONFIG_TYPE_MODEL_SELECTOR:
|
|
m, ok := v.(map[string]any)
|
|
if !ok {
|
|
return errors.New("setting " + config_name + " is not a map")
|
|
}
|
|
// check keys
|
|
if _, ok := m["provider"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing provider")
|
|
}
|
|
if _, ok := m["model"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing model")
|
|
}
|
|
if _, ok := m["model_type"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing model_type")
|
|
}
|
|
// check scope
|
|
if config.Scope != nil {
|
|
switch *config.Scope {
|
|
case string(MODEL_CONFIG_SCOPE_ALL):
|
|
// do nothing
|
|
case string(MODEL_CONFIG_SCOPE_LLM):
|
|
// do nothing
|
|
case string(MODEL_CONFIG_SCOPE_TEXT_EMBEDDING):
|
|
// do nothing
|
|
case string(MODEL_CONFIG_SCOPE_RERANK):
|
|
// score_threshold, top_n
|
|
if _, ok := m["score_threshold"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing score_threshold")
|
|
}
|
|
if _, ok := m["top_n"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing top_n")
|
|
}
|
|
case string(MODEL_CONFIG_SCOPE_TTS):
|
|
// voice
|
|
if _, ok := m["voice"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing voice")
|
|
}
|
|
case string(MODEL_CONFIG_SCOPE_SPEECH2TEXT):
|
|
// do nothing
|
|
case string(MODEL_CONFIG_SCOPE_MODERATION):
|
|
// do nothing
|
|
case string(MODEL_CONFIG_SCOPE_VISION):
|
|
// the same as llm
|
|
if _, ok := m["completion_params"]; !ok {
|
|
return errors.New("setting " + config_name + " is missing completion_params")
|
|
}
|
|
default:
|
|
return errors.New("setting " + config_name + " is not a valid model config scope")
|
|
}
|
|
}
|
|
// case CONFIG_TYPE_TOOL_SELECTOR:
|
|
// m, ok := v.(map[string]any)
|
|
// if !ok {
|
|
// return errors.New("setting " + config_name + " is not a map")
|
|
// }
|
|
// // check keys
|
|
// if _, ok := m["provider"]; !ok {
|
|
// return errors.New("setting " + config_name + " is missing provider")
|
|
// }
|
|
// if _, ok := m["tool"]; !ok {
|
|
// return errors.New("setting " + config_name + " is missing tool")
|
|
// }
|
|
// if _, ok := m["tool_type"]; !ok {
|
|
// return errors.New("setting " + config_name + " is missing tool_type")
|
|
// }
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|