From f5f8e638fa4f9c05b12ad8fc33809622043a97ba Mon Sep 17 00:00:00 2001 From: zyqzyq Date: Sat, 8 Aug 2026 16:06:00 +0800 Subject: [PATCH] feat: support reset_on_change parameter schema --- .../plugin_entities/agent_declaration.go | 27 ++++----- pkg/entities/plugin_entities/config.go | 23 ++++---- .../plugin_entities/datasource_declaration.go | 27 ++++----- .../plugin_entities/model_declaration.go | 23 ++++---- .../plugin_entities/tool_declaration.go | 1 + .../plugin_entities/tool_declaration_test.go | 58 +++++++++++++++++++ 6 files changed, 111 insertions(+), 48 deletions(-) diff --git a/pkg/entities/plugin_entities/agent_declaration.go b/pkg/entities/plugin_entities/agent_declaration.go index 7c008c08b..66a233341 100644 --- a/pkg/entities/plugin_entities/agent_declaration.go +++ b/pkg/entities/plugin_entities/agent_declaration.go @@ -58,19 +58,20 @@ func init() { } type AgentStrategyParameter struct { - Name string `json:"name" yaml:"name" validate:"required,gt=0,lt=1024"` - Label I18nObject `json:"label" yaml:"label" validate:"required"` - Help I18nObject `json:"help" yaml:"help" validate:"omitempty"` - Type AgentStrategyParameterType `json:"type" yaml:"type" validate:"required,agent_strategy_parameter_type"` - AutoGenerate *ParameterAutoGenerate `json:"auto_generate" yaml:"auto_generate" validate:"omitempty"` - Template *ParameterTemplate `json:"template" yaml:"template" validate:"omitempty"` - Scope *string `json:"scope" yaml:"scope" validate:"omitempty,max=1024,is_scope"` - Required bool `json:"required" yaml:"required"` - Default any `json:"default" yaml:"default" validate:"omitempty,is_basic_type"` - Min *float64 `json:"min" yaml:"min" validate:"omitempty"` - Max *float64 `json:"max" yaml:"max" validate:"omitempty"` - Precision *int `json:"precision" yaml:"precision" validate:"omitempty"` - Options []ParameterOption `json:"options" yaml:"options" validate:"omitempty,dive"` + Name string `json:"name" yaml:"name" validate:"required,gt=0,lt=1024"` + Label I18nObject `json:"label" yaml:"label" validate:"required"` + Help I18nObject `json:"help" yaml:"help" validate:"omitempty"` + Type AgentStrategyParameterType `json:"type" yaml:"type" validate:"required,agent_strategy_parameter_type"` + AutoGenerate *ParameterAutoGenerate `json:"auto_generate" yaml:"auto_generate" validate:"omitempty"` + Template *ParameterTemplate `json:"template" yaml:"template" validate:"omitempty"` + Scope *string `json:"scope" yaml:"scope" validate:"omitempty,max=1024,is_scope"` + Required bool `json:"required" yaml:"required"` + Default any `json:"default" yaml:"default" validate:"omitempty,is_basic_type"` + Min *float64 `json:"min" yaml:"min" validate:"omitempty"` + Max *float64 `json:"max" yaml:"max" validate:"omitempty"` + Precision *int `json:"precision" yaml:"precision" validate:"omitempty"` + Options []ParameterOption `json:"options" yaml:"options" validate:"omitempty,dive"` + ResetOnChange []string `json:"reset_on_change,omitempty" yaml:"reset_on_change,omitempty" validate:"omitempty,lte=16,dive,gt=0,lt=1024"` } type AgentStrategyOutputSchema map[string]any diff --git a/pkg/entities/plugin_entities/config.go b/pkg/entities/plugin_entities/config.go index e35b55114..5ac715fe4 100644 --- a/pkg/entities/plugin_entities/config.go +++ b/pkg/entities/plugin_entities/config.go @@ -281,17 +281,18 @@ func init() { } 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"` + 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"` + ResetOnChange []string `json:"reset_on_change,omitempty" yaml:"reset_on_change,omitempty" validate:"omitempty,lte=16,dive,gt=0,lt=1024"` } func init() { diff --git a/pkg/entities/plugin_entities/datasource_declaration.go b/pkg/entities/plugin_entities/datasource_declaration.go index 7f849d96a..4dc1e6c0e 100644 --- a/pkg/entities/plugin_entities/datasource_declaration.go +++ b/pkg/entities/plugin_entities/datasource_declaration.go @@ -67,19 +67,20 @@ func init() { } type DatasourceParameter struct { - Name string `json:"name" yaml:"name" validate:"required,gt=0,lt=1024"` - Label I18nObject `json:"label" yaml:"label" validate:"required"` - Type DatasourceParameterType `json:"type" yaml:"type" validate:"required,datasource_parameter_type"` - Scope *string `json:"scope" yaml:"scope" validate:"omitempty,max=1024,is_scope"` - Required bool `json:"required" yaml:"required"` - AutoGenerate *ParameterAutoGenerate `json:"auto_generate" yaml:"auto_generate" validate:"omitempty"` - Template *ParameterTemplate `json:"template" yaml:"template" validate:"omitempty"` - Default any `json:"default" yaml:"default" validate:"omitempty,is_basic_type"` - Min *float64 `json:"min" yaml:"min" validate:"omitempty"` - Max *float64 `json:"max" yaml:"max" validate:"omitempty"` - Precision *int `json:"precision" yaml:"precision" validate:"omitempty"` - Options []ParameterOption `json:"options" yaml:"options" validate:"omitempty,dive"` - Description I18nObject `json:"description" yaml:"description" validate:"required"` + Name string `json:"name" yaml:"name" validate:"required,gt=0,lt=1024"` + Label I18nObject `json:"label" yaml:"label" validate:"required"` + Type DatasourceParameterType `json:"type" yaml:"type" validate:"required,datasource_parameter_type"` + Scope *string `json:"scope" yaml:"scope" validate:"omitempty,max=1024,is_scope"` + Required bool `json:"required" yaml:"required"` + AutoGenerate *ParameterAutoGenerate `json:"auto_generate" yaml:"auto_generate" validate:"omitempty"` + Template *ParameterTemplate `json:"template" yaml:"template" validate:"omitempty"` + Default any `json:"default" yaml:"default" validate:"omitempty,is_basic_type"` + Min *float64 `json:"min" yaml:"min" validate:"omitempty"` + Max *float64 `json:"max" yaml:"max" validate:"omitempty"` + Precision *int `json:"precision" yaml:"precision" validate:"omitempty"` + Options []ParameterOption `json:"options" yaml:"options" validate:"omitempty,dive"` + ResetOnChange []string `json:"reset_on_change,omitempty" yaml:"reset_on_change,omitempty" validate:"omitempty,lte=16,dive,gt=0,lt=1024"` + Description I18nObject `json:"description" yaml:"description" validate:"required"` } type DatasourceOutputSchema map[string]any diff --git a/pkg/entities/plugin_entities/model_declaration.go b/pkg/entities/plugin_entities/model_declaration.go index 27d8bee78..9524ea16e 100644 --- a/pkg/entities/plugin_entities/model_declaration.go +++ b/pkg/entities/plugin_entities/model_declaration.go @@ -551,17 +551,18 @@ func (m *ModelProviderFormOption) UnmarshalYAML(value *yaml.Node) error { } type ModelProviderCredentialFormSchema struct { - Variable string `json:"variable" yaml:"variable" validate:"required,lt=256"` - Label I18nObject `json:"label" yaml:"label" validate:"required"` - Type ModelProviderFormType `json:"type" yaml:"type" validate:"required,model_provider_form_type"` - Required bool `json:"required" yaml:"required"` - Default *string `json:"default" yaml:"default" validate:"omitempty,lt=256"` - Options []ModelProviderFormOption `json:"options" yaml:"options" validate:"omitempty,lte=128,dive"` - Help *I18nObject `json:"help" yaml:"help" validate:"omitempty"` - URL *string `json:"url" yaml:"url" validate:"omitempty"` - Placeholder *I18nObject `json:"placeholder" yaml:"placeholder" validate:"omitempty"` - MaxLength int `json:"max_length" yaml:"max_length"` - ShowOn []ModelProviderFormShowOnObject `json:"show_on" yaml:"show_on" validate:"omitempty,lte=16,dive"` + Variable string `json:"variable" yaml:"variable" validate:"required,lt=256"` + Label I18nObject `json:"label" yaml:"label" validate:"required"` + Type ModelProviderFormType `json:"type" yaml:"type" validate:"required,model_provider_form_type"` + Required bool `json:"required" yaml:"required"` + Default *string `json:"default" yaml:"default" validate:"omitempty,lt=256"` + Options []ModelProviderFormOption `json:"options" yaml:"options" validate:"omitempty,lte=128,dive"` + Help *I18nObject `json:"help" yaml:"help" validate:"omitempty"` + URL *string `json:"url" yaml:"url" validate:"omitempty"` + Placeholder *I18nObject `json:"placeholder" yaml:"placeholder" validate:"omitempty"` + MaxLength int `json:"max_length" yaml:"max_length"` + ShowOn []ModelProviderFormShowOnObject `json:"show_on" yaml:"show_on" validate:"omitempty,lte=16,dive"` + ResetOnChange []string `json:"reset_on_change,omitempty" yaml:"reset_on_change,omitempty" validate:"omitempty,lte=16,dive,gt=0,lt=1024"` } func (m *ModelProviderCredentialFormSchema) UnmarshalJSON(data []byte) error { diff --git a/pkg/entities/plugin_entities/tool_declaration.go b/pkg/entities/plugin_entities/tool_declaration.go index adb1105ef..58fd7ac02 100644 --- a/pkg/entities/plugin_entities/tool_declaration.go +++ b/pkg/entities/plugin_entities/tool_declaration.go @@ -142,6 +142,7 @@ type ToolParameter struct { Multiple bool `json:"multiple" yaml:"multiple" validate:"omitempty"` Precision *int `json:"precision" yaml:"precision" validate:"omitempty"` Options []ParameterOption `json:"options" yaml:"options" validate:"omitempty,dive"` + ResetOnChange []string `json:"reset_on_change,omitempty" yaml:"reset_on_change,omitempty" validate:"omitempty,lte=16,dive,gt=0,lt=1024"` } type ToolDescription struct { diff --git a/pkg/entities/plugin_entities/tool_declaration_test.go b/pkg/entities/plugin_entities/tool_declaration_test.go index 564480ac5..079572b65 100644 --- a/pkg/entities/plugin_entities/tool_declaration_test.go +++ b/pkg/entities/plugin_entities/tool_declaration_test.go @@ -1117,6 +1117,64 @@ func TestParameterScope_Validate(t *testing.T) { } } +func TestToolParameterResetOnChange(t *testing.T) { + parameter := ToolParameter{ + Name: "child", + Label: I18nObject{ + EnUS: "Child", + }, + HumanDescription: I18nObject{ + EnUS: "Child parameter", + }, + Type: TOOL_PARAMETER_TYPE_DYNAMIC_SELECT, + Form: TOOL_PARAMETER_FORM_FORM, + ResetOnChange: []string{"parent"}, + } + + jsonBytes := parser.MarshalJsonBytes(parameter) + jsonParameter, err := parser.UnmarshalJsonBytes[ToolParameter](jsonBytes) + if err != nil { + t.Fatalf("failed to unmarshal JSON parameter: %v", err) + } + if len(jsonParameter.ResetOnChange) != 1 || jsonParameter.ResetOnChange[0] != "parent" { + t.Fatalf("unexpected JSON reset_on_change: %v", jsonParameter.ResetOnChange) + } + + yamlBytes := parser.MarshalYamlBytes(parameter) + yamlParameter, err := parser.UnmarshalYamlBytes[ToolParameter](yamlBytes) + if err != nil { + t.Fatalf("failed to unmarshal YAML parameter: %v", err) + } + if len(yamlParameter.ResetOnChange) != 1 || yamlParameter.ResetOnChange[0] != "parent" { + t.Fatalf("unexpected YAML reset_on_change: %v", yamlParameter.ResetOnChange) + } + + parameter.ResetOnChange = nil + jsonMap, err := parser.UnmarshalJsonBytes2Map(parser.MarshalJsonBytes(parameter)) + if err != nil { + t.Fatalf("failed to inspect JSON parameter: %v", err) + } + if _, ok := jsonMap["reset_on_change"]; ok { + t.Fatalf("reset_on_change should be omitted from JSON when unset: %v", jsonMap) + } + + yamlMap, err := parser.UnmarshalYaml2Map(parser.MarshalYamlBytes(parameter)) + if err != nil { + t.Fatalf("failed to inspect YAML parameter: %v", err) + } + if _, ok := yamlMap["reset_on_change"]; ok { + t.Fatalf("reset_on_change should be omitted from YAML when unset: %v", yamlMap) + } + + parameter.ResetOnChange = make([]string, 17) + for i := range parameter.ResetOnChange { + parameter.ResetOnChange[i] = "parent" + } + if _, err := parser.UnmarshalJsonBytes[ToolParameter](parser.MarshalJsonBytes(parameter)); err == nil { + t.Fatal("expected more than 16 reset_on_change entries to fail validation") + } +} + func TestToolName_Validate(t *testing.T) { data := parser.MarshalJsonBytes(ToolProviderIdentity{ Author: "author",