This is an automated email from the ASF dual-hosted git repository.

xuetaoli pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go-pixiu.git


The following commit(s) were added to refs/heads/develop by this push:
     new 98293ec4 fix(filter): deep copy complex filter configs 
(https://github.com/dubbo-go-pixiu/dubbo-go-pixiu/pull/38) (#814)
98293ec4 is described below

commit 98293ec41adfec6406161511d5bd70ee070f52ea
Author: dubbo-go-bot <[email protected]>
AuthorDate: Fri Nov 28 10:27:51 2025 +0800

    fix(filter): deep copy complex filter configs 
(https://github.com/dubbo-go-pixiu/dubbo-go-pixiu/pull/38) (#814)
    
    Some Pixiu filters have complex configurations (maps, slices, nested 
structs). Passing the factory.cfg pointer directly can cause in-flight requests 
to read inconsistent or modified configs when FilterManager.ReLoad() updates 
factory instances at runtime, violating the HttpFilterFactory interface 
contract.
    
    This commit implements DeepCopy() for complex filter configs and updates 
PrepareFilterChain to use it. Each filter instance now has its own independent 
config, preventing runtime inconsistencies.
    
    Affected files:
    - pkg/filter/auth/jwt/jwt.go
    - pkg/filter/authority/authority.go
    - pkg/filter/authority/config.go
    - pkg/filter/cors/cors.go
    - pkg/filter/csrf/csrf.go
    - pkg/filter/event/event.go
    - pkg/filter/failinject/filter.go
    - pkg/filter/http/grpcproxy/grpc.go
    - pkg/filter/mcp/mcpserver/filter.go
    - pkg/filter/sentinel/circuitbreaker/circuit_breaker.go
    - pkg/filter/sentinel/config.go
    - pkg/filter/sentinel/ratelimit/rate_limit.go
    - pkg/model/mcpserver.go
    
    Signed-off-by: Aetherance <[email protected]>
    Co-authored-by: The_INK <[email protected]>
    Co-authored-by: Aetherance <[email protected]>
---
 pkg/filter/auth/jwt/jwt.go                         |  66 +++++++-
 pkg/filter/authority/authority.go                  |   3 +-
 pkg/filter/authority/config.go                     |  40 +++++
 pkg/filter/cors/cors.go                            |  22 ++-
 pkg/filter/csrf/csrf.go                            |  22 ++-
 pkg/filter/event/event.go                          |   4 +-
 pkg/filter/failinject/filter.go                    |  29 +++-
 pkg/filter/http/grpcproxy/grpc.go                  |  34 +++-
 pkg/filter/mcp/mcpserver/filter.go                 |   3 +-
 .../sentinel/circuitbreaker/circuit_breaker.go     |  33 +++-
 pkg/filter/sentinel/config.go                      |  19 +++
 pkg/filter/sentinel/ratelimit/rate_limit.go        |  32 +++-
 pkg/model/mcpserver.go                             | 184 +++++++++++++++++++++
 13 files changed, 481 insertions(+), 10 deletions(-)

diff --git a/pkg/filter/auth/jwt/jwt.go b/pkg/filter/auth/jwt/jwt.go
index f4ab3bec..28561aad 100644
--- a/pkg/filter/auth/jwt/jwt.go
+++ b/pkg/filter/auth/jwt/jwt.go
@@ -82,7 +82,8 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg, errMsg: factory.errMsg, providerJwks: 
factory.providerJwks}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{cfg: factory.cfg.DeepCopy(), errMsg: factory.errMsg, 
providerJwks: factory.providerJwks}
        chain.AppendDecodeFilters(f)
        return nil
 }
@@ -225,3 +226,66 @@ func checkToken(value, prefix, providerName string, 
provider Provider) bool {
 func (factory *FilterFactory) Config() any {
        return factory.cfg
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+       cpConfig := *config
+
+       if config.Rules != nil {
+               cpConfig.Rules = make([]Rules, 0, len(config.Rules))
+               for _, rules := range config.Rules {
+                       cpRules := *rules.DeepCopy()
+                       cpConfig.Rules = append(cpConfig.Rules, cpRules)
+               }
+       }
+
+       if config.Providers != nil {
+               cpConfig.Providers = make([]Providers, 0, len(config.Providers))
+               for _, providers := range config.Providers {
+                       cpProviders := *providers.DeepCopy()
+                       cpConfig.Providers = append(cpConfig.Providers, 
cpProviders)
+               }
+       }
+
+       return &cpConfig
+}
+
+func (rules *Rules) DeepCopy() *Rules {
+       if rules == nil {
+               return nil
+       }
+       cpRules := *rules
+       cpRules.Requires = *rules.Requires.DeepCopy()
+       return &cpRules
+}
+
+func (providers *Providers) DeepCopy() *Providers {
+       if providers == nil {
+               return nil
+       }
+       cpProviders := *providers
+
+       if providers.Local != nil {
+               cpLocal := *providers.Local
+               cpProviders.Local = &cpLocal
+       }
+       if providers.Remote != nil {
+               cpRemote := *providers.Remote
+               cpProviders.Remote = &cpRemote
+       }
+       return &cpProviders
+}
+
+func (requires *Requires) DeepCopy() *Requires {
+       if requires == nil {
+               return nil
+       }
+       cpRequires := *requires
+       cpRequires.RequiresAll = make([]Requirement, len(requires.RequiresAll))
+       copy(cpRequires.RequiresAll, requires.RequiresAll)
+       return &cpRequires
+}
diff --git a/pkg/filter/authority/authority.go 
b/pkg/filter/authority/authority.go
index cf79e05d..84223ffa 100644
--- a/pkg/filter/authority/authority.go
+++ b/pkg/filter/authority/authority.go
@@ -61,7 +61,8 @@ func (factory *FilterFactory) Apply() error {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{cfg: factory.cfg.DeepCopy()}
        chain.AppendDecodeFilters(f)
        return nil
 }
diff --git a/pkg/filter/authority/config.go b/pkg/filter/authority/config.go
index d77810c0..a5625eb8 100644
--- a/pkg/filter/authority/config.go
+++ b/pkg/filter/authority/config.go
@@ -73,3 +73,43 @@ type (
        // LimitType the authority rule limit enum
        LimitType int32
 )
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (rule *AuthorityRule) DeepCopy() *AuthorityRule {
+       if rule == nil {
+               return nil
+       }
+
+       cp := *rule
+
+       if rule.Items != nil {
+               cp.Items = make([]string, len(rule.Items))
+               copy(cp.Items, rule.Items)
+       } else {
+               cp.Items = nil
+       }
+
+       return &cp
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (ac *AuthorityConfiguration) DeepCopy() *AuthorityConfiguration {
+       if ac == nil {
+               return nil
+       }
+
+       cp := *ac
+
+       if ac.Rules != nil {
+               cp.Rules = make([]AuthorityRule, len(ac.Rules))
+               for i := range ac.Rules {
+                       cp.Rules[i] = *ac.Rules[i].DeepCopy()
+               }
+       } else {
+               cp.Rules = nil
+       }
+
+       return &cp
+}
diff --git a/pkg/filter/cors/cors.go b/pkg/filter/cors/cors.go
index 780960f4..f56c2dc2 100644
--- a/pkg/filter/cors/cors.go
+++ b/pkg/filter/cors/cors.go
@@ -73,7 +73,8 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{cfg: factory.cfg.DeepCopy()}
        chain.AppendDecodeFilters(f)
        return nil
 }
@@ -132,3 +133,22 @@ func (factory *FilterFactory) Apply() error {
 func (factory *FilterFactory) Config() any {
        return factory.cfg
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+
+       cp := *config
+
+       if config.AllowOrigin != nil {
+               cp.AllowOrigin = make([]string, len(config.AllowOrigin))
+               copy(cp.AllowOrigin, config.AllowOrigin)
+       } else {
+               cp.AllowOrigin = nil
+       }
+
+       return &cp
+}
diff --git a/pkg/filter/csrf/csrf.go b/pkg/filter/csrf/csrf.go
index efedcd20..9ad2246c 100644
--- a/pkg/filter/csrf/csrf.go
+++ b/pkg/filter/csrf/csrf.go
@@ -74,7 +74,8 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{cfg: factory.cfg.DeepCopy()}
        chain.AppendDecodeFilters(f)
        return nil
 }
@@ -137,3 +138,22 @@ func (factory *FilterFactory) Apply() error {
 func (factory *FilterFactory) Config() any {
        return factory.cfg
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+
+       cp := *config
+
+       if config.IgnoreMethods != nil {
+               cp.IgnoreMethods = make([]string, len(config.IgnoreMethods))
+               copy(cp.IgnoreMethods, config.IgnoreMethods)
+       } else {
+               cp.IgnoreMethods = nil
+       }
+
+       return &cp
+}
diff --git a/pkg/filter/event/event.go b/pkg/filter/event/event.go
index 0d5cbc96..6dbd9fc4 100644
--- a/pkg/filter/event/event.go
+++ b/pkg/filter/event/event.go
@@ -63,7 +63,9 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg}
+       // Make a shallow copy of the factory config to avoid sharing the 
factory's pointer
+       cfgCopy := *factory.cfg
+       f := &Filter{cfg: &cfgCopy}
        chain.AppendDecodeFilters(f)
        return nil
 }
diff --git a/pkg/filter/failinject/filter.go b/pkg/filter/failinject/filter.go
index f7a664b3..c2f9ec92 100644
--- a/pkg/filter/failinject/filter.go
+++ b/pkg/filter/failinject/filter.go
@@ -57,8 +57,9 @@ func (factory *FilterFactory) Config() any {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *contextHttp.HttpContext, 
chain filter.FilterChain) error {
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
        f := Filter{
-               cfg: factory.cfg,
+               cfg: factory.cfg.DeepCopy(),
        }
        chain.AppendDecodeFilters(f)
        return nil
@@ -151,3 +152,29 @@ func percentage(odds int) bool {
        num := rand.Intn(100) + 1 // NOSONAR
        return num <= odds
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+
+       cp := &Config{}
+
+       if config.Rules != nil {
+               cp.Rules = make(map[URI]*Rule, len(config.Rules))
+               for k, r := range config.Rules {
+                       if r == nil {
+                               cp.Rules[k] = nil
+                       } else {
+                               rr := *r
+                               cp.Rules[k] = &rr
+                       }
+               }
+       } else {
+               cp.Rules = nil
+       }
+
+       return cp
+}
diff --git a/pkg/filter/http/grpcproxy/grpc.go 
b/pkg/filter/http/grpcproxy/grpc.go
index cfedb01f..ca43e317 100644
--- a/pkg/filter/http/grpcproxy/grpc.go
+++ b/pkg/filter/http/grpcproxy/grpc.go
@@ -152,7 +152,8 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       f := &Filter{cfg: factory.cfg, descriptor: factory.descriptor, pools: 
factory.pools, extReg: factory.extReg, registered: factory.registered}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{cfg: factory.cfg.DeepCopy(), descriptor: 
factory.descriptor, pools: factory.pools, extReg: factory.extReg, registered: 
factory.registered}
        chain.AppendDecodeFilters(f)
        return nil
 }
@@ -431,3 +432,34 @@ func configCheck(cfg *Config) error {
        }
        return nil
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+
+       cp := *config
+
+       if config.Rules != nil {
+               cp.Rules = make([]*Rule, len(config.Rules))
+               for i, r := range config.Rules {
+                       if r == nil {
+                               cp.Rules[i] = nil
+                               continue
+                       }
+                       nr := &Rule{
+                               Selector: r.Selector,
+                               Match: Match{
+                                       Method: r.Match.Method,
+                               },
+                       }
+                       cp.Rules[i] = nr
+               }
+       } else {
+               cp.Rules = nil
+       }
+
+       return &cp
+}
diff --git a/pkg/filter/mcp/mcpserver/filter.go 
b/pkg/filter/mcp/mcpserver/filter.go
index 1a56cb75..9707c519 100644
--- a/pkg/filter/mcp/mcpserver/filter.go
+++ b/pkg/filter/mcp/mcpserver/filter.go
@@ -108,8 +108,9 @@ func (f *FilterFactory) PrepareFilterChain(_ 
*contexthttp.HttpContext, chain fil
        sseHandler := transport.NewSSEHandler(sessionManager)
        contentNegotiator := transport.NewContentNegotiator()
 
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
        mcpFilter := &MCPServerFilter{
-               cfg:               f.cfg,
+               cfg:               f.cfg.DeepCopy(),
                registry:          f.registry,
                errorHandler:      NewErrorHandler(),
                responseBuilder:   NewResponseBuilder(),
diff --git a/pkg/filter/sentinel/circuitbreaker/circuit_breaker.go 
b/pkg/filter/sentinel/circuitbreaker/circuit_breaker.go
index fd22ad88..c8ad9e55 100644
--- a/pkg/filter/sentinel/circuitbreaker/circuit_breaker.go
+++ b/pkg/filter/sentinel/circuitbreaker/circuit_breaker.go
@@ -77,8 +77,9 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
        return &FilterFactory{cfg: &Config{}}, nil
 }
 
+// Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
 func (factory *FilterFactory) PrepareFilterChain(ctx *http.HttpContext, chain 
filter.FilterChain) error {
-       chain.AppendDecodeFilters(&Filter{cfg: factory.cfg, matcher: 
factory.matcher})
+       chain.AppendDecodeFilters(&Filter{cfg: factory.cfg.DeepCopy(), matcher: 
factory.matcher})
        return nil
 }
 
@@ -165,3 +166,33 @@ func loadRules(rules []*circuitbreaker.Rule) error {
        }
        return nil
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+       cpConfig := *config
+
+       if config.Resources != nil {
+               cpConfig.Resources = make([]*pkgs.Resource, 
len(config.Resources))
+               for index, resource := range config.Resources {
+                       if resource != nil {
+                               cpConfig.Resources[index] = resource.DeepCopy()
+                       }
+               }
+       }
+
+       if config.Rules != nil {
+               cpConfig.Rules = make([]*circuitbreaker.Rule, len(config.Rules))
+               for index, rule := range config.Rules {
+                       if rule != nil {
+                               cpRule := *rule
+                               cpConfig.Rules[index] = &cpRule
+                       }
+               }
+       }
+
+       return &cpConfig
+}
diff --git a/pkg/filter/sentinel/config.go b/pkg/filter/sentinel/config.go
index 8fc84edc..cc672f1a 100644
--- a/pkg/filter/sentinel/config.go
+++ b/pkg/filter/sentinel/config.go
@@ -40,3 +40,22 @@ type (
        // MatchStrategy API match strategy
        MatchStrategy int32
 )
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (resource *Resource) DeepCopy() *Resource {
+       if resource == nil {
+               return nil
+       }
+       cpResource := *resource
+       if resource.Items != nil {
+               cpResource.Items = make([]*Item, len(resource.Items))
+               for index, orig := range resource.Items {
+                       if orig != nil {
+                               cp := *orig
+                               cpResource.Items[index] = &cp
+                       }
+               }
+       }
+       return &cpResource
+}
diff --git a/pkg/filter/sentinel/ratelimit/rate_limit.go 
b/pkg/filter/sentinel/ratelimit/rate_limit.go
index 5ea4ad91..ee7516ab 100644
--- a/pkg/filter/sentinel/ratelimit/rate_limit.go
+++ b/pkg/filter/sentinel/ratelimit/rate_limit.go
@@ -68,7 +68,8 @@ func (p *Plugin) CreateFilterFactory() 
(filter.HttpFilterFactory, error) {
 }
 
 func (factory *FilterFactory) PrepareFilterChain(ctx *contexthttp.HttpContext, 
chain filter.FilterChain) error {
-       f := &Filter{conf: factory.conf, matcher: factory.matcher}
+       // Deep copy config to avoid pointer sharing (factory.cfg may change at 
runtime)
+       f := &Filter{conf: factory.conf.DeepCopy(), matcher: factory.matcher}
        chain.AppendDecodeFilters(f)
        return nil
 }
@@ -131,3 +132,32 @@ func OnRulesUpdate(rules []*Rule) {
                logger.Warnf("rate limit load rules err: %v", err)
        }
 }
+
+// DeepCopy returns a new independent copy of Config
+// // Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *Config) DeepCopy() *Config {
+       if config == nil {
+               return nil
+       }
+       cpConfig := *config
+       if config.Resources != nil {
+               cpConfig.Resources = make([]*pkgs.Resource, 
len(config.Resources))
+               for index, resource := range config.Resources {
+                       if resource != nil {
+                               cpConfig.Resources[index] = resource.DeepCopy()
+                       }
+               }
+       }
+
+       if config.Rules != nil {
+               cpConfig.Rules = make([]*Rule, len(config.Rules))
+               for index, rule := range config.Rules {
+                       if rule != nil {
+                               cpRule := *rule
+                               cpConfig.Rules[index] = &cpRule
+                       }
+               }
+       }
+
+       return &cpConfig
+}
diff --git a/pkg/model/mcpserver.go b/pkg/model/mcpserver.go
index 45f270a4..27d89732 100644
--- a/pkg/model/mcpserver.go
+++ b/pkg/model/mcpserver.go
@@ -222,3 +222,187 @@ func GetPathParameterNames(pathTemplate string) []string {
 
        return names
 }
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *McpServerConfig) DeepCopy() *McpServerConfig {
+       if config == nil {
+               return nil
+       }
+
+       cpConfig := *config
+
+       // Deep copy Tools
+       if config.Tools != nil {
+               cpConfig.Tools = make([]ToolConfig, len(config.Tools))
+               for i := range config.Tools {
+                       cpConfig.Tools[i] = *config.Tools[i].DeepCopy()
+               }
+       }
+
+       // Deep copy Resources
+       if config.Resources != nil {
+               cpConfig.Resources = make([]ResourceConfig, 
len(config.Resources))
+               copy(cpConfig.Resources, config.Resources)
+       }
+
+       // Deep copy ResourceTemplates
+       if config.ResourceTemplates != nil {
+               cpConfig.ResourceTemplates = make([]ResourceTemplateConfig, 
len(config.ResourceTemplates))
+               for i := range config.ResourceTemplates {
+                       cpConfig.ResourceTemplates[i] = 
*config.ResourceTemplates[i].DeepCopy()
+               }
+       }
+
+       // Deep copy Prompts
+       if config.Prompts != nil {
+               cpConfig.Prompts = make([]PromptConfig, len(config.Prompts))
+               for i := range config.Prompts {
+                       cpConfig.Prompts[i] = *config.Prompts[i].DeepCopy()
+               }
+       }
+
+       return &cpConfig
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (toolConfig *ToolConfig) DeepCopy() *ToolConfig {
+       if toolConfig == nil {
+               return nil
+       }
+       cpConfig := *toolConfig
+       cpConfig.Request = *toolConfig.Request.DeepCopy()
+
+       if toolConfig.Args != nil {
+               cpConfig.Args = make([]ArgConfig, len(toolConfig.Args))
+               for index := range toolConfig.Args {
+                       argPtr := &toolConfig.Args[index]
+                       cpConfig.Args[index] = *argPtr.DeepCopy()
+               }
+       }
+
+       return &cpConfig
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *RequestConfig) DeepCopy() *RequestConfig {
+       if config == nil {
+               return nil
+       }
+       cpConfig := *config
+       if config.Headers != nil {
+               cpConfig.Headers = make(map[string]string, len(config.Headers))
+               for k, v := range config.Headers {
+                       cpConfig.Headers[k] = v
+               }
+       }
+
+       return &cpConfig
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *ArgConfig) DeepCopy() *ArgConfig {
+       if config == nil {
+               return nil
+       }
+       cpConfig := *config
+       if config.Enum != nil {
+               cpConfig.Enum = make([]string, len(config.Enum))
+               copy(cpConfig.Enum, config.Enum)
+       }
+       return &cpConfig
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (param *ResourceTemplateParameter) DeepCopy() *ResourceTemplateParameter {
+       if param == nil {
+               return nil
+       }
+
+       cpParam := *param
+
+       if param.Enum != nil {
+               cpParam.Enum = make([]string, len(param.Enum))
+               copy(cpParam.Enum, param.Enum)
+       }
+
+       return &cpParam
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (ann *ResourceTemplateAnnotations) DeepCopy() 
*ResourceTemplateAnnotations {
+       if ann == nil {
+               return nil
+       }
+
+       cpAnn := *ann
+
+       // Deep copy Audience slice
+       if ann.Audience != nil {
+               cpAnn.Audience = make([]string, len(ann.Audience))
+               copy(cpAnn.Audience, ann.Audience)
+       }
+
+       // Deep copy Priority pointer
+       if ann.Priority != nil {
+               p := *ann.Priority
+               cpAnn.Priority = &p
+       }
+
+       return &cpAnn
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *ResourceTemplateConfig) DeepCopy() *ResourceTemplateConfig {
+       if config == nil {
+               return nil
+       }
+
+       cpConfig := *config
+
+       // Deep copy Parameters slice
+       if config.Parameters != nil {
+               cpConfig.Parameters = make([]ResourceTemplateParameter, 
len(config.Parameters))
+               for i := range config.Parameters {
+                       paramPtr := &config.Parameters[i]
+                       cpConfig.Parameters[i] = *paramPtr.DeepCopy()
+               }
+       }
+
+       // Deep copy Annotations pointer
+       if config.Annotations != nil {
+               cpConfig.Annotations = config.Annotations.DeepCopy()
+       }
+
+       return &cpConfig
+}
+
+// DeepCopy returns a new independent copy of Config
+// Deep copy slices/maps to avoid sharing pointers with the factory
+func (config *PromptConfig) DeepCopy() *PromptConfig {
+       if config == nil {
+               return nil
+       }
+
+       cp := *config
+
+       // Deep copy Arguments slice
+       if config.Arguments != nil {
+               cp.Arguments = make([]PromptArgumentConfig, 
len(config.Arguments))
+               copy(cp.Arguments, config.Arguments)
+       }
+
+       // Deep copy Messages slice
+       if config.Messages != nil {
+               cp.Messages = make([]PromptMessageConfig, len(config.Messages))
+               copy(cp.Messages, config.Messages)
+       }
+
+       return &cp
+}

Reply via email to