feat:add CLI param-override templates with visual editor and apply on first rule match

This commit is contained in:
Seefs
2026-02-25 15:08:23 +08:00
parent db0b452ea2
commit 0519446571
8 changed files with 570 additions and 60 deletions

View File

@@ -18,6 +18,8 @@ type ChannelAffinityRule struct {
ValueRegex string `json:"value_regex"`
TTLSeconds int `json:"ttl_seconds"`
ParamOverrideTemplate map[string]interface{} `json:"param_override_template,omitempty"`
SkipRetryOnFailure bool `json:"skip_retry_on_failure,omitempty"`
IncludeUsingGroup bool `json:"include_using_group"`
@@ -32,6 +34,44 @@ type ChannelAffinitySetting struct {
Rules []ChannelAffinityRule `json:"rules"`
}
var codexCliPassThroughHeaders = []string{
"Originator",
"Session_id",
"User-Agent",
"X-Codex-Beta-Features",
"X-Codex-Turn-Metadata",
}
var claudeCliPassThroughHeaders = []string{
"X-Stainless-Arch",
"X-Stainless-Lang",
"X-Stainless-Os",
"X-Stainless-Package-Version",
"X-Stainless-Retry-Count",
"X-Stainless-Runtime",
"X-Stainless-Runtime-Version",
"X-Stainless-Timeout",
"User-Agent",
"X-App",
"Anthropic-Beta",
"Anthropic-Dangerous-Direct-Browser-Access",
"Anthropic-Version",
}
func buildPassHeaderTemplate(headers []string) map[string]interface{} {
clonedHeaders := make([]string, 0, len(headers))
clonedHeaders = append(clonedHeaders, headers...)
return map[string]interface{}{
"operations": []map[string]interface{}{
{
"mode": "pass_headers",
"value": clonedHeaders,
"keep_origin": true,
},
},
}
}
var channelAffinitySetting = ChannelAffinitySetting{
Enabled: true,
SwitchOnSuccess: true,
@@ -39,32 +79,34 @@ var channelAffinitySetting = ChannelAffinitySetting{
DefaultTTLSeconds: 3600,
Rules: []ChannelAffinityRule{
{
Name: "codex trace",
Name: "codex cli trace",
ModelRegex: []string{"^gpt-.*$"},
PathRegex: []string{"/v1/responses"},
KeySources: []ChannelAffinityKeySource{
{Type: "gjson", Path: "prompt_cache_key"},
},
ValueRegex: "",
TTLSeconds: 0,
SkipRetryOnFailure: false,
IncludeUsingGroup: true,
IncludeRuleName: true,
UserAgentInclude: nil,
ValueRegex: "",
TTLSeconds: 0,
ParamOverrideTemplate: buildPassHeaderTemplate(codexCliPassThroughHeaders),
SkipRetryOnFailure: false,
IncludeUsingGroup: true,
IncludeRuleName: true,
UserAgentInclude: nil,
},
{
Name: "claude code trace",
Name: "claude cli trace",
ModelRegex: []string{"^claude-.*$"},
PathRegex: []string{"/v1/messages"},
KeySources: []ChannelAffinityKeySource{
{Type: "gjson", Path: "metadata.user_id"},
},
ValueRegex: "",
TTLSeconds: 0,
SkipRetryOnFailure: false,
IncludeUsingGroup: true,
IncludeRuleName: true,
UserAgentInclude: nil,
ValueRegex: "",
TTLSeconds: 0,
ParamOverrideTemplate: buildPassHeaderTemplate(claudeCliPassThroughHeaders),
SkipRetryOnFailure: false,
IncludeUsingGroup: true,
IncludeRuleName: true,
UserAgentInclude: nil,
},
},
}