feat: publish sanitized custom.97 source
This commit is contained in:
1022 files changed
+69903
-19207
No files matched your search
+134
-105
@@ -3,6 +3,7 @@ package middleware
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/constant"
|
||||
"github.com/QuantumNous/new-api/dto"
|
||||
"github.com/QuantumNous/new-api/i18n"
|
||||
"github.com/QuantumNous/new-api/logger"
|
||||
"github.com/QuantumNous/new-api/model"
|
||||
pluginruntime "github.com/QuantumNous/new-api/pkg/jsplugin"
|
||||
@@ -77,11 +79,12 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if err != nil {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_request",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_request err=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
err.Error()),
|
||||
)
|
||||
status := http.StatusBadRequest
|
||||
status := invalidRequestStatus(err)
|
||||
if errors.Is(err, errTaskPluginUnsupportedMediaType) {
|
||||
status = http.StatusUnsupportedMediaType
|
||||
}
|
||||
@@ -93,10 +96,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if pinned.Route.Type == pluginruntime.RouteTypeQuery && bodyKind != string(pluginruntime.BodyNone) || pinned.Route.Type != pluginruntime.RouteTypeQuery && bodyKind != string(pluginruntime.BodyJSON) {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=body_kind_mismatch body_kind=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
bodyKind,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=body_kind_mismatch body_kind=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
bodyKind),
|
||||
)
|
||||
detail := "this route requires a JSON body"
|
||||
if pinned.Route.Type == pluginruntime.RouteTypeQuery {
|
||||
@@ -124,10 +127,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if claimedModel == "" || !slices.Contains(pinned.Route.Models, claimedModel) {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=model_not_allowed model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
claimedModel,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=model_not_allowed model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
claimedModel),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, fmt.Sprintf("model %q is not allowed on this route", claimedModel))
|
||||
return
|
||||
@@ -135,15 +138,18 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
}
|
||||
|
||||
hookStarted := time.Now()
|
||||
resolvedValue, err := pinned.Plugin.Engine.CallMember(c.Request.Context(), "native", pinned.Route.Decode, requestContext.JSValue())
|
||||
resolvedValue, requestBodyText, err := pinned.Plugin.Engine.CallPathWithMemberJSON(
|
||||
c.Request.Context(), 0, pinned.Plugin.Meta.JSONTextMember("requestBody"),
|
||||
"native", []string{pinned.Route.Decode}, requestContext.JSValueFor(pinned.Plugin.Meta),
|
||||
)
|
||||
if err != nil {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=hook_failed err=%q elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
err.Error(),
|
||||
time.Since(hookStarted).Milliseconds(),
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=hook_failed err=%q elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
err.Error(),
|
||||
time.Since(hookStarted).Milliseconds()),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginHookDetail(err))
|
||||
return
|
||||
@@ -152,10 +158,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !ok {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=result_not_object elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
time.Since(hookStarted).Milliseconds(),
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=result_not_object elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
time.Since(hookStarted).Milliseconds()),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
@@ -164,16 +170,16 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !ok {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=missing_kind elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
time.Since(hookStarted).Milliseconds(),
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=missing_kind elapsed_ms=%d",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
time.Since(hookStarted).Milliseconds()),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
}
|
||||
if _, forbidden := resolved["renderer"]; forbidden {
|
||||
logger.LogWarn(c, "task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=forbidden_renderer", generation, pinned.Plugin.Meta.Key)
|
||||
logger.LogWarn(c, common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=forbidden_renderer", generation, pinned.Plugin.Meta.Key))
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
}
|
||||
@@ -184,9 +190,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !valid || strings.TrimSpace(modelName) == "" {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_model",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_model",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, "decoded request is missing a model")
|
||||
return
|
||||
@@ -195,10 +201,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !owned {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=model_not_owned model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
modelName,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=model_not_owned model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
modelName),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, fmt.Sprintf("model %q is not served by this plugin", modelName))
|
||||
return
|
||||
@@ -206,10 +212,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if len(pinned.Route.Models) > 0 && !slices.Contains(pinned.Route.Models, modelName) {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=resolved_model_not_allowed model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
modelName,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=resolved_model_not_allowed model=%q",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
modelName),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, fmt.Sprintf("model %q is not allowed on this route", modelName))
|
||||
return
|
||||
@@ -220,9 +226,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !actionOK {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_action",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_action",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
@@ -236,6 +242,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
c.Set(pluginruntime.ContextKeyRouteRequest, requestContext)
|
||||
}
|
||||
c.Set("task_request", requestContext.RequestBody)
|
||||
if requestBodyText != nil {
|
||||
c.Set(pluginruntime.ContextKeyRequestBodyText, requestBodyText)
|
||||
}
|
||||
c.Set("resolved_task_model", modelName)
|
||||
c.Set("expected_task_plugin_key", pinned.Plugin.Meta.Key)
|
||||
c.Set("task_plugin_key", pinned.Plugin.Meta.Key)
|
||||
@@ -248,10 +257,10 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if intentErr := applyOriginTaskIntent(c, resolved, pinned.Plugin.Meta); intentErr != nil {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=origin_task reason=%s",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
intentErr.Code,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=origin_task reason=%s",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
intentErr.Code),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, intentErr.StatusCode, intentErr.Message)
|
||||
return
|
||||
@@ -272,9 +281,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if pinned.Route.Type != pluginruntime.RouteTypeDynamic {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=query_from_non_dynamic_route",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=query_from_non_dynamic_route",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
@@ -283,9 +292,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
if !valid {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_query_result",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=invalid_query_result",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
@@ -303,9 +312,9 @@ func PrepareTaskPluginRoute() gin.HandlerFunc {
|
||||
default:
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=unsupported_kind",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=route event=prepare_rejected generation=%d plugin=%q stage=resolve_request reason=unsupported_kind",
|
||||
generation,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortTaskPluginRouteErrorDetail(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
}
|
||||
@@ -326,7 +335,7 @@ func PinTaskPluginEndpoint() gin.HandlerFunc {
|
||||
modelRequest, err := getModelFromRequest(c)
|
||||
if err != nil {
|
||||
if _, _, protocolPath := pluginruntime.LookupHostProtocolOperation(c.Request.Method, c.Request.URL.Path); protocolPath {
|
||||
abortWithOpenAiMessage(c, http.StatusBadRequest, "Invalid task protocol request")
|
||||
abortWithOpenAiMessage(c, invalidRequestStatus(err), i18n.T(c, i18n.MsgDistributorInvalidRequest, map[string]any{"Error": err.Error()}))
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
@@ -525,9 +534,9 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if !pluginruntime.SupportsHostProtocol(pinned.Protocol) {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=protocol_check reason=unsupported_protocol",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=protocol_check reason=unsupported_protocol",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortWithOpenAiMessage(c, http.StatusNotImplemented, "Task protocol bridge is not available")
|
||||
return
|
||||
@@ -536,9 +545,9 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if err != nil {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_request",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_request",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
status := http.StatusBadRequest
|
||||
if errors.Is(err, errTaskPluginUnsupportedMediaType) {
|
||||
@@ -566,10 +575,10 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if !allowedBody {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=body_kind_mismatch body_kind=%q",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
bodyKind,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=body_kind_mismatch body_kind=%q",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
bodyKind),
|
||||
)
|
||||
detail := "unsupported request body for this operation"
|
||||
if len(pinned.Operation.BodyKinds) == 1 && pinned.Operation.BodyKinds[0] == pluginruntime.BodyJSON {
|
||||
@@ -586,9 +595,9 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if !ok {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_stream_flag",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=request_decode reason=invalid_stream_flag",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortWithOpenAiMessage(c, http.StatusBadRequest, "stream must be a boolean")
|
||||
return
|
||||
@@ -610,6 +619,7 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
}
|
||||
accepted := make([]pluginruntime.ProtocolBinding, 0, len(candidates))
|
||||
var resolved map[string]any
|
||||
var resolvedBodyText json.RawMessage
|
||||
var failures []string
|
||||
rejectedPlugins := make(map[string][]string)
|
||||
for _, candidate := range candidates {
|
||||
@@ -618,9 +628,10 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
candidateContext.Operation = candidate.Operation.Name
|
||||
// Parsing belongs to durable submission; disconnecting only stops
|
||||
// the later Responses observation.
|
||||
resolvedValue, callErr := candidate.Plugin.Engine.CallPathWithAdmissionTimeout(
|
||||
resolvedValue, requestBodyText, callErr := candidate.Plugin.Engine.CallPathWithMemberJSON(
|
||||
context.WithoutCancel(c.Request.Context()), pluginruntime.DefaultCallTimeout,
|
||||
"protocols", []string{candidate.Protocol, "decodeRequest"}, candidateContext.JSValue(),
|
||||
candidate.Plugin.Meta.JSONTextMember("requestBody"),
|
||||
"protocols", []string{candidate.Protocol, "decodeRequest"}, candidateContext.JSValueFor(candidate.Plugin.Meta),
|
||||
)
|
||||
result, resultOK := resolvedValue.(map[string]any)
|
||||
detail := ""
|
||||
@@ -645,8 +656,8 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
detail = fmt.Sprintf("model %q is not served by this plugin", model)
|
||||
}
|
||||
if detail != "" {
|
||||
logger.LogWarn(c, "task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=parse_request reason=%s err=%q elapsed_ms=%d",
|
||||
pinned.Generation.Number, candidate.Plugin.Meta.Key, reason, detail, time.Since(hookStarted).Milliseconds())
|
||||
logger.LogWarn(c, common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=parse_request reason=%s err=%q elapsed_ms=%d",
|
||||
pinned.Generation.Number, candidate.Plugin.Meta.Key, reason, detail, time.Since(hookStarted).Milliseconds()))
|
||||
if _, seen := rejectedPlugins[detail]; !seen {
|
||||
failures = append(failures, detail)
|
||||
}
|
||||
@@ -656,6 +667,7 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
accepted = append(accepted, candidate)
|
||||
if resolved == nil {
|
||||
resolved = result
|
||||
resolvedBodyText = requestBodyText
|
||||
protocolContext = candidateContext
|
||||
}
|
||||
}
|
||||
@@ -683,9 +695,9 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if !ok {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=parse_request reason=invalid_action",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=parse_request reason=invalid_action",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key),
|
||||
)
|
||||
abortWithOpenAiMessage(c, http.StatusBadRequest, taskPluginInvalidRouteResult)
|
||||
return
|
||||
@@ -697,6 +709,9 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
}
|
||||
c.Set(pluginruntime.ContextKeyRouteRequest, requestContext)
|
||||
c.Set("task_request", requestContext.RequestBody)
|
||||
if resolvedBodyText != nil {
|
||||
c.Set(pluginruntime.ContextKeyRequestBodyText, resolvedBodyText)
|
||||
}
|
||||
c.Set("resolved_task_model", resolvedModel)
|
||||
c.Set("expected_task_plugin_key", pinned.Plugin.Meta.Key)
|
||||
c.Set("task_plugin_key", pinned.Plugin.Meta.Key)
|
||||
@@ -709,10 +724,10 @@ func PrepareTaskPluginEndpoint() gin.HandlerFunc {
|
||||
if intentErr := applyOriginTaskIntent(c, resolved, pinned.Plugin.Meta); intentErr != nil {
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=origin_task reason=%s",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
intentErr.Code,
|
||||
common.LogText("task_plugin subsystem=endpoint event=prepare_rejected generation=%d plugin=%q stage=origin_task reason=%s",
|
||||
pinned.Generation.Number,
|
||||
pinned.Plugin.Meta.Key,
|
||||
intentErr.Code),
|
||||
)
|
||||
abortWithOpenAiMessage(c, intentErr.StatusCode, intentErr.Message, types.ErrorCode(intentErr.Code))
|
||||
return
|
||||
@@ -791,6 +806,9 @@ func buildTaskPluginRouteRequest(c *gin.Context) (pluginruntime.RouteRequestCont
|
||||
return requestContext, err
|
||||
}
|
||||
requestContext.Body = map[string]any{"kind": string(pluginruntime.BodyJSON), "value": value}
|
||||
// Body storage never changes its bytes in place (a rewrite stores a
|
||||
// new copy), so the text needs no copy of its own.
|
||||
requestContext.BodyText = raw
|
||||
case mediaType == "application/x-www-form-urlencoded":
|
||||
storage, storageErr := common.GetBodyStorage(c)
|
||||
if storageErr != nil {
|
||||
@@ -933,7 +951,7 @@ func buildTaskPluginRouteRequest(c *gin.Context) (pluginruntime.RouteRequestCont
|
||||
if !utf8.ValidString(field) || len(field) > maxTaskPluginFieldNameBytes {
|
||||
return requestContext, fmt.Errorf("invalid multipart file field name")
|
||||
}
|
||||
for _, header := range headers {
|
||||
for index, header := range headers {
|
||||
if !utf8.ValidString(header.Filename) || len(header.Filename) > maxTaskPluginFilenameBytes {
|
||||
return requestContext, fmt.Errorf("invalid multipart filename")
|
||||
}
|
||||
@@ -947,7 +965,7 @@ func buildTaskPluginRouteRequest(c *gin.Context) (pluginruntime.RouteRequestCont
|
||||
if header.Size < 0 || header.Size > int64(fileLimitMB)<<20 {
|
||||
return requestContext, fmt.Errorf("multipart file exceeds %d MB", fileLimitMB)
|
||||
}
|
||||
ref := "request_file:" + field
|
||||
ref := pluginruntime.FileReference(field, index)
|
||||
files = append(files, map[string]any{"ref": ref, "field": field, "filename": header.Filename, "mimeType": header.Header.Get("Content-Type"), "size": header.Size})
|
||||
}
|
||||
}
|
||||
@@ -1163,10 +1181,10 @@ func renderTaskPluginQuery(
|
||||
for _, task := range tasks {
|
||||
tasksByID[task.TaskID] = task
|
||||
}
|
||||
views := make([]map[string]any, 0, len(taskIDs))
|
||||
views := make([]dto.TaskView, 0, len(taskIDs))
|
||||
for _, taskID := range taskIDs {
|
||||
task := tasksByID[taskID]
|
||||
if task == nil {
|
||||
if task == nil || !task.ResultRetrievable() {
|
||||
logger.LogDebug(
|
||||
c,
|
||||
"task_plugin subsystem=query event=lookup_failed generation=%d plugin=%q reason=task_not_found requested=%d found=%d",
|
||||
@@ -1183,25 +1201,20 @@ func renderTaskPluginQuery(
|
||||
abortTaskPluginRouteError(c, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var viewValue map[string]any
|
||||
encoded, marshalErr := common.Marshal(view)
|
||||
if marshalErr != nil {
|
||||
abortTaskPluginRouteError(c, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if unmarshalErr := common.Unmarshal(encoded, &viewValue); unmarshalErr != nil {
|
||||
abortTaskPluginRouteError(c, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
views = append(views, viewValue)
|
||||
views = append(views, view)
|
||||
}
|
||||
|
||||
var rendererInput any = views
|
||||
if !multiple {
|
||||
rendererInput = views[0]
|
||||
}
|
||||
encoded, err := common.Marshal(rendererInput)
|
||||
if err != nil {
|
||||
abortTaskPluginRouteError(c, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
renderStarted := time.Now()
|
||||
result, err := pinned.Plugin.Engine.CallPath(c.Request.Context(), "native", []string{renderer}, requestContext.JSValue(), rendererInput)
|
||||
result, err := pinned.Plugin.Engine.CallPath(c.Request.Context(), "native", []string{renderer}, requestContext.JSValue(), pluginruntime.RawJSON(encoded))
|
||||
if err != nil {
|
||||
logger.LogDebug(
|
||||
c,
|
||||
@@ -1264,18 +1277,18 @@ func RespondTaskPluginError(c *gin.Context, taskErr *dto.TaskError) bool {
|
||||
}
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=error_renderer_failed plugin=%q reason=hook_failed status=%d err=%q",
|
||||
pinned.Plugin.Meta.Key,
|
||||
sanitized.HTTPStatus,
|
||||
callErr.Error(),
|
||||
common.LogText("task_plugin subsystem=route event=error_renderer_failed plugin=%q reason=hook_failed status=%d err=%q",
|
||||
pinned.Plugin.Meta.Key,
|
||||
sanitized.HTTPStatus,
|
||||
callErr.Error()),
|
||||
)
|
||||
}
|
||||
logger.LogWarn(
|
||||
c,
|
||||
"task_plugin subsystem=route event=error_rendered plugin=%q renderer=host_fallback status=%d code=%q",
|
||||
pinned.Plugin.Meta.Key,
|
||||
sanitized.HTTPStatus,
|
||||
sanitized.Code,
|
||||
common.LogText("task_plugin subsystem=route event=error_rendered plugin=%q renderer=host_fallback status=%d code=%q",
|
||||
pinned.Plugin.Meta.Key,
|
||||
sanitized.HTTPStatus,
|
||||
sanitized.Code),
|
||||
)
|
||||
message := sanitized.Message
|
||||
if requestID != "" {
|
||||
@@ -1373,8 +1386,11 @@ func logTaskPluginChannelDecision(c *gin.Context, channel *model.Channel, modelN
|
||||
return
|
||||
}
|
||||
identityMode := "legacy_channel_type"
|
||||
if channel.Type == constant.ChannelTypeTaskPlugin {
|
||||
switch channel.Type {
|
||||
case constant.ChannelTypeTaskPlugin:
|
||||
identityMode = "type59_setting"
|
||||
case constant.ChannelTypeNewAPI:
|
||||
identityMode = "type60_setting"
|
||||
}
|
||||
logger.LogDebug(
|
||||
c,
|
||||
@@ -1412,7 +1428,7 @@ func PrepareTaskPluginSubmit() gin.HandlerFunc {
|
||||
)
|
||||
var requestBody map[string]any
|
||||
if err := common.UnmarshalBodyReusable(c, &requestBody); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": gin.H{"message": err.Error(), "type": "invalid_request_error"}})
|
||||
c.AbortWithStatusJSON(invalidRequestStatus(err), gin.H{"error": gin.H{"message": err.Error(), "type": "invalid_request_error"}})
|
||||
return
|
||||
}
|
||||
modelName, _ := requestBody["model"].(string)
|
||||
@@ -1442,6 +1458,19 @@ func PrepareTaskPluginSubmit() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
c.Set("task_request", requestBody)
|
||||
if plugin.Meta.PreservesJSONOrder() {
|
||||
// The body as stored after any model rewrite: the text hooks get.
|
||||
storage, err := common.GetBodyStorage(c)
|
||||
var raw []byte
|
||||
if err == nil {
|
||||
raw, err = storage.Bytes()
|
||||
}
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": gin.H{"message": err.Error(), "type": "invalid_request_error"}})
|
||||
return
|
||||
}
|
||||
c.Set(pluginruntime.ContextKeyRequestBodyText, json.RawMessage(raw))
|
||||
}
|
||||
c.Set("resolved_task_model", modelName)
|
||||
c.Set("expected_task_plugin_key", pluginKey)
|
||||
service.AppendTaskPluginIdentityFilter(c, pluginKey)
|
||||
|
||||
Reference in new issue
Block a user