diff --git a/config.example.yaml b/config.example.yaml index 425fd2de..092ba926 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -407,7 +407,7 @@ nonstream-keepalive-interval: 0 # - models: # - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*") # protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity -# form-protocol: "responses" # restricts the rule to the source protocol, options: openai, responses, gemini, claude +# from-protocol: "responses" # restricts the rule to the source protocol, options: openai, responses, gemini, claude # headers: # all configured request headers must match; values support "*" wildcards # X-Client-Tier: "tenant-*-region-*" # match: # all payload JSON paths must equal the configured values diff --git a/internal/config/config.go b/internal/config/config.go index fa63bfb9..a9b794bb 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -346,8 +346,8 @@ type PayloadModelRule struct { Protocol string `yaml:"protocol" json:"protocol"` // Headers restricts the rule to requests whose headers match all configured wildcard patterns. Headers map[string]string `yaml:"headers" json:"headers"` - // FormProtocol restricts the rule to a specific source protocol (e.g., "gemini", "responses"). - FormProtocol string `yaml:"form-protocol" json:"form-protocol"` + // FromProtocol restricts the rule to a specific source protocol (e.g., "gemini", "responses"). + FromProtocol string `yaml:"from-protocol" json:"from-protocol"` // Match requires payload JSON paths to equal the configured values. Match []map[string]any `yaml:"match" json:"match"` // NotMatch requires payload JSON paths to not equal the configured values. diff --git a/internal/runtime/executor/helps/payload_helpers.go b/internal/runtime/executor/helps/payload_helpers.go index 6362d9e7..33f53ca9 100644 --- a/internal/runtime/executor/helps/payload_helpers.go +++ b/internal/runtime/executor/helps/payload_helpers.go @@ -25,7 +25,7 @@ func ApplyPayloadConfigWithRoot(cfg *config.Config, model, protocol, root string } // ApplyPayloadConfigWithRequest applies payload config using source protocol and request header gates. -func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProtocol, root string, payload, original []byte, requestedModel string, requestPath string, headers http.Header) []byte { +func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, fromProtocol, root string, payload, original []byte, requestedModel string, requestPath string, headers http.Header) []byte { if cfg == nil || len(payload) == 0 { return payload } @@ -55,7 +55,7 @@ func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProt // Apply default rules: first write wins per field across all matching rules. for i := range rules.Default { rule := &rules.Default[i] - if !payloadModelRulesMatch(rule.Models, protocol, formProtocol, headers, out, root, candidates) { + if !payloadModelRulesMatch(rule.Models, protocol, fromProtocol, headers, out, root, candidates) { continue } for path, value := range rule.Params { @@ -82,7 +82,7 @@ func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProt // Apply default raw rules: first write wins per field across all matching rules. for i := range rules.DefaultRaw { rule := &rules.DefaultRaw[i] - if !payloadModelRulesMatch(rule.Models, protocol, formProtocol, headers, out, root, candidates) { + if !payloadModelRulesMatch(rule.Models, protocol, fromProtocol, headers, out, root, candidates) { continue } for path, value := range rule.Params { @@ -113,7 +113,7 @@ func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProt // Apply override rules: last write wins per field across all matching rules. for i := range rules.Override { rule := &rules.Override[i] - if !payloadModelRulesMatch(rule.Models, protocol, formProtocol, headers, out, root, candidates) { + if !payloadModelRulesMatch(rule.Models, protocol, fromProtocol, headers, out, root, candidates) { continue } for path, value := range rule.Params { @@ -133,7 +133,7 @@ func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProt // Apply override raw rules: last write wins per field across all matching rules. for i := range rules.OverrideRaw { rule := &rules.OverrideRaw[i] - if !payloadModelRulesMatch(rule.Models, protocol, formProtocol, headers, out, root, candidates) { + if !payloadModelRulesMatch(rule.Models, protocol, fromProtocol, headers, out, root, candidates) { continue } for path, value := range rule.Params { @@ -157,7 +157,7 @@ func ApplyPayloadConfigWithRequest(cfg *config.Config, model, protocol, formProt // Apply filter rules: remove matching paths from payload. for i := range rules.Filter { rule := &rules.Filter[i] - if !payloadModelRulesMatch(rule.Models, protocol, formProtocol, headers, out, root, candidates) { + if !payloadModelRulesMatch(rule.Models, protocol, fromProtocol, headers, out, root, candidates) { continue } for _, path := range rule.Params { @@ -199,7 +199,7 @@ func isImagesEndpointRequestPath(path string) bool { return false } -func payloadModelRulesMatch(rules []config.PayloadModelRule, protocol string, formProtocol string, headers http.Header, payload []byte, root string, models []string) bool { +func payloadModelRulesMatch(rules []config.PayloadModelRule, protocol string, fromProtocol string, headers http.Header, payload []byte, root string, models []string) bool { if len(rules) == 0 || len(models) == 0 { return false } @@ -212,7 +212,7 @@ func payloadModelRulesMatch(rules []config.PayloadModelRule, protocol string, fo if ep := strings.TrimSpace(entry.Protocol); ep != "" && protocol != "" && !strings.EqualFold(ep, protocol) { continue } - if !payloadFormProtocolMatches(entry.FormProtocol, formProtocol) { + if !payloadFromProtocolMatches(entry.FromProtocol, fromProtocol) { continue } if !payloadHeadersMatch(headers, entry.Headers) { @@ -366,19 +366,19 @@ func normalizedPayloadJSON(data []byte) (any, bool) { return out, true } -func payloadFormProtocolMatches(pattern, formProtocol string) bool { - pattern = normalizePayloadFormProtocol(pattern) +func payloadFromProtocolMatches(pattern, fromProtocol string) bool { + pattern = normalizePayloadFromProtocol(pattern) if pattern == "" { return true } - formProtocol = normalizePayloadFormProtocol(formProtocol) - if formProtocol == "" { + fromProtocol = normalizePayloadFromProtocol(fromProtocol) + if fromProtocol == "" { return false } - return strings.EqualFold(pattern, formProtocol) + return strings.EqualFold(pattern, fromProtocol) } -func normalizePayloadFormProtocol(protocol string) string { +func normalizePayloadFromProtocol(protocol string) string { protocol = strings.ToLower(strings.TrimSpace(protocol)) switch protocol { case "openai-response", "openai-responses", "response": diff --git a/internal/runtime/executor/helps/payload_helpers_disable_image_generation_test.go b/internal/runtime/executor/helps/payload_helpers_disable_image_generation_test.go index e9fd33f6..a6627c83 100644 --- a/internal/runtime/executor/helps/payload_helpers_disable_image_generation_test.go +++ b/internal/runtime/executor/helps/payload_helpers_disable_image_generation_test.go @@ -171,13 +171,13 @@ func TestApplyPayloadConfigWithRequest_HeaderGateRequiresWildcardMatch(t *testin } } -func TestApplyPayloadConfigWithRequest_FormProtocolGateUsesSourceProtocol(t *testing.T) { +func TestApplyPayloadConfigWithRequest_FromProtocolGateUsesSourceProtocol(t *testing.T) { cfg := &config.Config{ Payload: config.PayloadConfig{ Override: []config.PayloadRule{ { Models: []config.PayloadModelRule{ - {Name: "gpt-*", Protocol: "openai", FormProtocol: "responses"}, + {Name: "gpt-*", Protocol: "openai", FromProtocol: "responses"}, }, Params: map[string]any{ "metadata.source": "responses", @@ -185,7 +185,7 @@ func TestApplyPayloadConfigWithRequest_FormProtocolGateUsesSourceProtocol(t *tes }, { Models: []config.PayloadModelRule{ - {Name: "gpt-*", Protocol: "openai", FormProtocol: "openai"}, + {Name: "gpt-*", Protocol: "openai", FromProtocol: "openai"}, }, Params: map[string]any{ "metadata.source": "openai",