refactor(runtime): rename FormProtocol to FromProtocol across payload handling logic
- Updated variable, function, and struct names from `FormProtocol` to `FromProtocol` for clarity. - Adjusted related payload matching and normalization logic. - Updated tests and examples to align with the new naming convention.
This commit is contained in:
+1
-1
@@ -407,7 +407,7 @@ nonstream-keepalive-interval: 0
|
|||||||
# - models:
|
# - models:
|
||||||
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
|
# - 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
|
# 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
|
# headers: # all configured request headers must match; values support "*" wildcards
|
||||||
# X-Client-Tier: "tenant-*-region-*"
|
# X-Client-Tier: "tenant-*-region-*"
|
||||||
# match: # all payload JSON paths must equal the configured values
|
# match: # all payload JSON paths must equal the configured values
|
||||||
|
|||||||
@@ -346,8 +346,8 @@ type PayloadModelRule struct {
|
|||||||
Protocol string `yaml:"protocol" json:"protocol"`
|
Protocol string `yaml:"protocol" json:"protocol"`
|
||||||
// Headers restricts the rule to requests whose headers match all configured wildcard patterns.
|
// Headers restricts the rule to requests whose headers match all configured wildcard patterns.
|
||||||
Headers map[string]string `yaml:"headers" json:"headers"`
|
Headers map[string]string `yaml:"headers" json:"headers"`
|
||||||
// FormProtocol restricts the rule to a specific source protocol (e.g., "gemini", "responses").
|
// FromProtocol restricts the rule to a specific source protocol (e.g., "gemini", "responses").
|
||||||
FormProtocol string `yaml:"form-protocol" json:"form-protocol"`
|
FromProtocol string `yaml:"from-protocol" json:"from-protocol"`
|
||||||
// Match requires payload JSON paths to equal the configured values.
|
// Match requires payload JSON paths to equal the configured values.
|
||||||
Match []map[string]any `yaml:"match" json:"match"`
|
Match []map[string]any `yaml:"match" json:"match"`
|
||||||
// NotMatch requires payload JSON paths to not equal the configured values.
|
// NotMatch requires payload JSON paths to not equal the configured values.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func ApplyPayloadConfigWithRoot(cfg *config.Config, model, protocol, root string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApplyPayloadConfigWithRequest applies payload config using source protocol and request header gates.
|
// 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 {
|
if cfg == nil || len(payload) == 0 {
|
||||||
return payload
|
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.
|
// Apply default rules: first write wins per field across all matching rules.
|
||||||
for i := range rules.Default {
|
for i := range rules.Default {
|
||||||
rule := &rules.Default[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
for path, value := range rule.Params {
|
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.
|
// Apply default raw rules: first write wins per field across all matching rules.
|
||||||
for i := range rules.DefaultRaw {
|
for i := range rules.DefaultRaw {
|
||||||
rule := &rules.DefaultRaw[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
for path, value := range rule.Params {
|
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.
|
// Apply override rules: last write wins per field across all matching rules.
|
||||||
for i := range rules.Override {
|
for i := range rules.Override {
|
||||||
rule := &rules.Override[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
for path, value := range rule.Params {
|
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.
|
// Apply override raw rules: last write wins per field across all matching rules.
|
||||||
for i := range rules.OverrideRaw {
|
for i := range rules.OverrideRaw {
|
||||||
rule := &rules.OverrideRaw[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
for path, value := range rule.Params {
|
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.
|
// Apply filter rules: remove matching paths from payload.
|
||||||
for i := range rules.Filter {
|
for i := range rules.Filter {
|
||||||
rule := &rules.Filter[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
for _, path := range rule.Params {
|
for _, path := range rule.Params {
|
||||||
@@ -199,7 +199,7 @@ func isImagesEndpointRequestPath(path string) bool {
|
|||||||
return false
|
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 {
|
if len(rules) == 0 || len(models) == 0 {
|
||||||
return false
|
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) {
|
if ep := strings.TrimSpace(entry.Protocol); ep != "" && protocol != "" && !strings.EqualFold(ep, protocol) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !payloadFormProtocolMatches(entry.FormProtocol, formProtocol) {
|
if !payloadFromProtocolMatches(entry.FromProtocol, fromProtocol) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !payloadHeadersMatch(headers, entry.Headers) {
|
if !payloadHeadersMatch(headers, entry.Headers) {
|
||||||
@@ -366,19 +366,19 @@ func normalizedPayloadJSON(data []byte) (any, bool) {
|
|||||||
return out, true
|
return out, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func payloadFormProtocolMatches(pattern, formProtocol string) bool {
|
func payloadFromProtocolMatches(pattern, fromProtocol string) bool {
|
||||||
pattern = normalizePayloadFormProtocol(pattern)
|
pattern = normalizePayloadFromProtocol(pattern)
|
||||||
if pattern == "" {
|
if pattern == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
formProtocol = normalizePayloadFormProtocol(formProtocol)
|
fromProtocol = normalizePayloadFromProtocol(fromProtocol)
|
||||||
if formProtocol == "" {
|
if fromProtocol == "" {
|
||||||
return false
|
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))
|
protocol = strings.ToLower(strings.TrimSpace(protocol))
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case "openai-response", "openai-responses", "response":
|
case "openai-response", "openai-responses", "response":
|
||||||
|
|||||||
@@ -171,13 +171,13 @@ func TestApplyPayloadConfigWithRequest_HeaderGateRequiresWildcardMatch(t *testin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyPayloadConfigWithRequest_FormProtocolGateUsesSourceProtocol(t *testing.T) {
|
func TestApplyPayloadConfigWithRequest_FromProtocolGateUsesSourceProtocol(t *testing.T) {
|
||||||
cfg := &config.Config{
|
cfg := &config.Config{
|
||||||
Payload: config.PayloadConfig{
|
Payload: config.PayloadConfig{
|
||||||
Override: []config.PayloadRule{
|
Override: []config.PayloadRule{
|
||||||
{
|
{
|
||||||
Models: []config.PayloadModelRule{
|
Models: []config.PayloadModelRule{
|
||||||
{Name: "gpt-*", Protocol: "openai", FormProtocol: "responses"},
|
{Name: "gpt-*", Protocol: "openai", FromProtocol: "responses"},
|
||||||
},
|
},
|
||||||
Params: map[string]any{
|
Params: map[string]any{
|
||||||
"metadata.source": "responses",
|
"metadata.source": "responses",
|
||||||
@@ -185,7 +185,7 @@ func TestApplyPayloadConfigWithRequest_FormProtocolGateUsesSourceProtocol(t *tes
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Models: []config.PayloadModelRule{
|
Models: []config.PayloadModelRule{
|
||||||
{Name: "gpt-*", Protocol: "openai", FormProtocol: "openai"},
|
{Name: "gpt-*", Protocol: "openai", FromProtocol: "openai"},
|
||||||
},
|
},
|
||||||
Params: map[string]any{
|
Params: map[string]any{
|
||||||
"metadata.source": "openai",
|
"metadata.source": "openai",
|
||||||
|
|||||||
Reference in New Issue
Block a user