feat: publish sanitized custom.97 source
This commit is contained in:
1022 files changed
+69903
-19207
No files matched your search
+39
-24
@@ -57,7 +57,7 @@ func Distribute() func(c *gin.Context) {
|
||||
service.AppendTaskPluginIdentityFilter(c, c.GetString("expected_task_plugin_key"))
|
||||
modelRequest, shouldSelectChannel, err := getModelRequest(c)
|
||||
if err != nil {
|
||||
abortWithOpenAiMessage(c, http.StatusBadRequest, i18n.T(c, i18n.MsgDistributorInvalidRequest, map[string]any{"Error": err.Error()}))
|
||||
abortWithOpenAiMessage(c, invalidRequestStatus(err), i18n.T(c, i18n.MsgDistributorInvalidRequest, map[string]any{"Error": err.Error()}))
|
||||
return
|
||||
}
|
||||
requestedStream = modelRequest.Stream || strings.Contains(c.Request.URL.Path, "streamGenerateContent") || strings.EqualFold(c.GetHeader("Upgrade"), "websocket")
|
||||
@@ -130,14 +130,7 @@ func Distribute() func(c *gin.Context) {
|
||||
message = i18n.T(c, selectErr.MessageID, selectErr.Params)
|
||||
}
|
||||
if service.RequestRoutingPolicy(c) != nil && selectErr.NoAvailableChannel {
|
||||
if c.GetBool("pool_degradation_unavailable") {
|
||||
message = "Group quality checks are temporarily unavailable. Please retry later."
|
||||
} else if wait := c.GetInt("pool_retry_after"); wait > 0 {
|
||||
message = fmt.Sprintf("No eligible group is currently available; failed groups are cooling down or being checked. Retry after %d seconds.", wait)
|
||||
c.Header("Retry-After", fmt.Sprint(wait))
|
||||
} else {
|
||||
message = "No eligible group is available for this model under the current pool and quality settings."
|
||||
}
|
||||
message = noAvailableGroupPoolMessage(c)
|
||||
}
|
||||
rejectionMessage = message
|
||||
abortWithOpenAiMessage(c, selectErr.StatusCode, message, selectErr.Code)
|
||||
@@ -157,6 +150,13 @@ func Distribute() func(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func noAvailableGroupPoolMessage(c *gin.Context) string {
|
||||
if wait := c.GetInt("pool_retry_after"); wait > 0 {
|
||||
c.Header("Retry-After", fmt.Sprint(wait))
|
||||
}
|
||||
return "分组池中无条件内可用分组"
|
||||
}
|
||||
|
||||
// noAvailableChannelMessage explains a 503 for a task-plugin-claimed model.
|
||||
// The response tells the caller the model is plugin-claimed without naming the
|
||||
// plugin; the candidate plugin keys go to the server log under the request id.
|
||||
@@ -175,7 +175,7 @@ func noAvailableChannelMessage(c *gin.Context, group, modelName string) string {
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.LogWarn(c, "task_plugin subsystem=distribution event=no_available_channel group=%q model=%q plugins=%q reason=no_eligible_channel", group, modelName, strings.Join(keys, ","))
|
||||
logger.LogWarn(c, common.LogText("task_plugin subsystem=distribution event=no_available_channel group=%q model=%q plugins=%q reason=no_eligible_channel", group, modelName, strings.Join(keys, ",")))
|
||||
return i18n.T(c, i18n.MsgDistributorNoAvailableChannelTaskPlugin, map[string]any{"Group": group, "Model": modelName})
|
||||
}
|
||||
return i18n.T(c, i18n.MsgDistributorNoAvailableChannel, map[string]any{"Group": group, "Model": modelName})
|
||||
@@ -190,11 +190,11 @@ func channelMatchesExpectedTaskPlugin(c *gin.Context, channel *model.Channel, ex
|
||||
return true
|
||||
}
|
||||
}
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin {
|
||||
return expected != "" && channel.GetSetting().TaskPluginKey == expected
|
||||
}
|
||||
if expected == "" {
|
||||
return true
|
||||
return channel.Type != constant.ChannelTypeTaskPlugin
|
||||
}
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin || channel.Type == constant.ChannelTypeNewAPI {
|
||||
return channel.GetSetting().BindsTaskPlugin(expected)
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
@@ -224,6 +224,7 @@ func pinnedEndpointCandidateForChannel(c *gin.Context, channel *model.Channel, e
|
||||
}
|
||||
expectedOwned := false
|
||||
selected := jsplugin.ProtocolBinding{}
|
||||
setting := channel.GetSetting()
|
||||
for _, candidate := range candidates {
|
||||
if candidate.Plugin == nil {
|
||||
continue
|
||||
@@ -231,8 +232,12 @@ func pinnedEndpointCandidateForChannel(c *gin.Context, channel *model.Channel, e
|
||||
if candidate.Plugin.Meta.Key == expected {
|
||||
expectedOwned = true
|
||||
}
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin {
|
||||
if channel.GetSetting().TaskPluginKey == candidate.Plugin.Meta.Key {
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin || channel.Type == constant.ChannelTypeNewAPI {
|
||||
// A New API channel may bind several candidates. The first bound
|
||||
// candidate in generation order executes, so the billing provider
|
||||
// depends only on the channel and the request, never on which
|
||||
// channels an earlier retry attempt happened to try.
|
||||
if selected.Plugin == nil && setting.BindsTaskPlugin(candidate.Plugin.Meta.Key) {
|
||||
selected = candidate
|
||||
}
|
||||
continue
|
||||
@@ -258,17 +263,13 @@ func getModelFromRequest(c *gin.Context) (*ModelRequest, error) {
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(c.Request.Header.Get("Content-Type"), "application/json") {
|
||||
modelRequest, err := getModelFromJSONBody(c)
|
||||
if err != nil {
|
||||
return nil, errors.New(i18n.T(c, i18n.MsgDistributorInvalidRequest, map[string]any{"Error": err.Error()}))
|
||||
}
|
||||
return modelRequest, nil
|
||||
return getModelFromJSONBody(c)
|
||||
}
|
||||
|
||||
var modelRequest ModelRequest
|
||||
err := common.UnmarshalBodyReusable(c, &modelRequest)
|
||||
if err != nil {
|
||||
return nil, errors.New(i18n.T(c, i18n.MsgDistributorInvalidRequest, map[string]any{"Error": err.Error()}))
|
||||
return nil, err
|
||||
}
|
||||
return &modelRequest, nil
|
||||
}
|
||||
@@ -402,7 +403,7 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
|
||||
midjourneyRequest := taskdto.MidjourneyRequest{}
|
||||
err = common.UnmarshalBodyReusable(c, &midjourneyRequest)
|
||||
if err != nil {
|
||||
return nil, false, errors.New(i18n.T(c, i18n.MsgDistributorInvalidMidjourney, map[string]any{"Error": err.Error()}))
|
||||
return nil, false, err
|
||||
}
|
||||
midjourneyModel, mjErr, success := service.GetMjRequestModel(relayMode, &midjourneyRequest)
|
||||
if mjErr != nil {
|
||||
@@ -491,6 +492,13 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
|
||||
modelRequest.Model = c.Param("model")
|
||||
}
|
||||
}
|
||||
// The routing name is also the billing name, so a model named in the body
|
||||
// must not replace it: DeepSeek ignores that field.
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/v1/tools/search") {
|
||||
modelRequest.Model = constant.DeepSeekSearchModel
|
||||
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/tools/fetch") {
|
||||
modelRequest.Model = constant.DeepSeekFetchModel
|
||||
}
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
|
||||
modelRequest.Model = common.GetStringIfEmpty(modelRequest.Model, "dall-e")
|
||||
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/edits") {
|
||||
@@ -620,8 +628,15 @@ func SetupContextForSelectedChannel(c *gin.Context, channel *model.Channel, mode
|
||||
common.SetContextKey(c, constant.ContextKeyChannelCreateTime, channel.CreatedTime)
|
||||
common.SetContextKey(c, constant.ContextKeyChannelSetting, channel.GetSetting())
|
||||
common.SetContextKey(c, constant.ContextKeyChannelOtherSetting, channel.GetOtherSettings())
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin {
|
||||
switch channel.Type {
|
||||
case constant.ChannelTypeTaskPlugin:
|
||||
c.Set("task_plugin_key", channel.GetSetting().TaskPluginKey)
|
||||
case constant.ChannelTypeNewAPI:
|
||||
// The bound plugin verified above executes; ordinary requests through
|
||||
// the same gateway channel carry no pinned plugin.
|
||||
if executing := c.GetString("expected_task_plugin_key"); executing != "" {
|
||||
c.Set("task_plugin_key", executing)
|
||||
}
|
||||
}
|
||||
logTaskPluginChannelDecision(c, channel, modelName, "channel_selected", "")
|
||||
paramOverride := channel.GetParamOverride()
|
||||
|
||||
Reference in new issue
Block a user