refactor: advanced custom channel route editor (#6865)

* refactor: advanced custom channel route editor

* fix(channels): show raw balance response from balance cell
This commit is contained in:
Seefs
2026-08-18 17:31:21 +08:00
committed by GitHub
parent 3dda1d50c6
commit 2b0efd8484
21 changed files with 1551 additions and 506 deletions
+20 -3
View File
@@ -194,6 +194,14 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
}
func (a *Adaptor) BuildModelListRequest(info *relaycommon.RelayInfo) (string, http.Header, error) {
return a.buildManagementRequest(info, dto.AdvancedCustomModelListPath)
}
func (a *Adaptor) BuildBalanceRequest(info *relaycommon.RelayInfo) (string, http.Header, error) {
return a.buildManagementRequest(info, dto.AdvancedCustomBalancePath)
}
func (a *Adaptor) buildManagementRequest(info *relaycommon.RelayInfo, managementPath string) (string, http.Header, error) {
if info == nil {
return "", nil, errors.New("missing relay info")
}
@@ -204,16 +212,25 @@ func (a *Adaptor) BuildModelListRequest(info *relaycommon.RelayInfo) (string, ht
if err := config.Validate(); err != nil {
return "", nil, err
}
route, ok := config.ModelListRoute()
var route dto.AdvancedCustomRoute
var ok bool
switch managementPath {
case dto.AdvancedCustomModelListPath:
route, ok = config.ModelListRoute()
case dto.AdvancedCustomBalancePath:
route, ok = config.BalanceRoute()
default:
return "", nil, fmt.Errorf("unsupported advanced custom management path: %s", managementPath)
}
if !ok {
return "", nil, errors.New("advanced custom channel does not configure a /v1/models route")
return "", nil, fmt.Errorf("advanced custom channel does not configure a %s route", managementPath)
}
converter := strings.TrimSpace(route.Converter)
if converter == "" {
converter = relayconvert.ConverterNone
}
if converter != relayconvert.ConverterNone {
return "", nil, fmt.Errorf("converter %q does not support model list requests", converter)
return "", nil, fmt.Errorf("converter %q does not support %s requests", converter, managementPath)
}
requestURL, err := buildRouteURL(route, converter, info)
@@ -422,6 +422,49 @@ func TestAdaptorBuildModelListRequestRequiresConfiguredRoute(t *testing.T) {
assert.Contains(t, err.Error(), "does not configure a /v1/models route")
}
func TestAdaptorBuildBalanceRequestUsesConfiguredRoute(t *testing.T) {
info := advancedCustomRelayInfo(&dto.AdvancedCustomConfig{
Routes: []dto.AdvancedCustomRoute{
{
IncomingPath: dto.AdvancedCustomModelListPath,
UpstreamPath: "/provider/models",
},
{
IncomingPath: dto.AdvancedCustomBalancePath,
UpstreamPath: "/provider/balance?existing=1",
Auth: &dto.AdvancedCustomRouteAuth{
Type: dto.AdvancedCustomAuthTypeQuery,
Name: "token",
Value: "prefix-{api_key}",
},
},
},
})
requestURL, header, err := (&Adaptor{}).BuildBalanceRequest(info)
require.NoError(t, err)
parsedURL, err := url.Parse(requestURL)
require.NoError(t, err)
assert.Equal(t, "/provider/balance", parsedURL.Path)
assert.Equal(t, "1", parsedURL.Query().Get("existing"))
assert.Equal(t, "prefix-sk-test", parsedURL.Query().Get("token"))
assert.Empty(t, header.Get("Authorization"))
}
func TestAdaptorBuildBalanceRequestRequiresConfiguredRoute(t *testing.T) {
info := advancedCustomRelayInfo(&dto.AdvancedCustomConfig{
Routes: []dto.AdvancedCustomRoute{{
IncomingPath: dto.AdvancedCustomModelListPath,
UpstreamPath: "/provider/models",
}},
})
_, _, err := (&Adaptor{}).BuildBalanceRequest(info)
require.Error(t, err)
assert.Contains(t, err.Error(), "does not configure a /v1/dashboard/billing/credit_grants route")
}
func TestAdaptorConvertsResponsesRequestToOpenAIChatUpstream(t *testing.T) {
adaptor := &Adaptor{}
info := advancedCustomRelayInfo(&dto.AdvancedCustomConfig{