From c72c43aaaa6894eeae59650d2640dda9c4f414ad Mon Sep 17 00:00:00 2001 From: easyai Date: Wed, 22 Jul 2026 03:50:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(universal):=20=E5=85=BC=E5=AE=B9=20server-m?= =?UTF-8?q?ain=20=E8=84=9A=E6=9C=AC=E8=AF=AD=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充历史脚本依赖的参数预处理上下文,并识别嵌套同步结果,使迁移后的 Universal 图片通道可按原配置执行。 --- apps/api/internal/clients/universal.go | 21 +++++++++++ apps/api/internal/clients/universal_test.go | 41 +++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/apps/api/internal/clients/universal.go b/apps/api/internal/clients/universal.go index f2a998a..976a20e 100644 --- a/apps/api/internal/clients/universal.go +++ b/apps/api/internal/clients/universal.go @@ -44,6 +44,8 @@ func (c UniversalClient) Run(ctx context.Context, request Request) (Response, er if err != nil { return Response{}, annotateResponseError(err, submitRequestID, startedAt, time.Now()) } + submitResult = universalEffectiveResult(submitResult) + submitRequestID = firstNonEmptyString(submitRequestID, requestIDFromResult(submitResult)) if isUniversalSuccess(submitResult) && submitResult["data"] != nil { return Response{ Result: normalizeUniversalResult(request, submitResult, ""), @@ -157,6 +159,7 @@ func (c UniversalClient) universalPollUntilDone(ctx context.Context, executor *s if err != nil { return nil, "", annotateResponseError(err, firstNonEmptyString(pollRequestID, requestID, upstreamTaskID), pollStarted, pollFinished) } + result = universalEffectiveResult(result) lastResult = result requestID = firstNonEmptyString(pollRequestID, requestID, requestIDFromResult(result), upstreamTaskID) if isUniversalSuccess(result) { @@ -239,6 +242,10 @@ func universalScriptContext(request Request, modelType string, payload map[strin return selectedBase + "/" + strings.TrimLeft(path, "/") } context["creatRequestURL"] = context["createRequestURL"] + context["processedParams"] = cloneBody(request.Body) + context["preProcessParams"] = func(params map[string]any, _ ...string) map[string]any { + return cloneMapAny(params) + } context["resolveGetTaskURL"] = func(taskID string) string { return resolveUniversalTaskURL(request.Candidate.PlatformConfig, taskID) } @@ -389,6 +396,20 @@ func universalStatus(result map[string]any) string { return strings.ToLower(strings.TrimSpace(firstNonEmptyString(result["status"], result["state"], result["task_status"]))) } +func universalEffectiveResult(result map[string]any) map[string]any { + nested, ok := result["result"].(map[string]any) + if !ok || nested == nil || isUniversalFailure(result) { + return result + } + out := cloneMapAny(nested) + for _, key := range []string{"status", "request_id", "requestId", "upstream_task_id", "task_id", "taskId", "id"} { + if out[key] == nil && result[key] != nil { + out[key] = result[key] + } + } + return out +} + func universalTaskID(result map[string]any) string { return firstNonEmptyString(result["upstream_task_id"], result["task_id"], result["taskId"], result["id"]) } diff --git a/apps/api/internal/clients/universal_test.go b/apps/api/internal/clients/universal_test.go index 325004d..f08d084 100644 --- a/apps/api/internal/clients/universal_test.go +++ b/apps/api/internal/clients/universal_test.go @@ -92,6 +92,47 @@ func TestUniversalClientDefaultSubmitAndPoll(t *testing.T) { } } +func TestUniversalClientSupportsServerMainScriptContextAndNestedResult(t *testing.T) { + request := Request{ + Kind: "images.generations", + ModelType: "image_generate", + Model: "custom-image", + Body: map[string]any{"model": "custom-image", "prompt": "hello"}, + Candidate: testUniversalCandidate(map[string]any{ + "customGetParamsScript": map[string]any{ + "image_generate": `async function getParams(params, context) { + const processed = await context.preProcessParams(params, context.type); + return { prompt: processed.prompt + "-" + context.processedParams.prompt }; + }`, + }, + "customSubmitScript": map[string]any{ + "image_generate": `async function submitTask(payload) { + return { + status: "success", + result: { + status: "success", + data: [{ url: "https://cdn.example/" + payload.prompt + ".png" }] + } + }; + }`, + }, + }), + } + + response, err := (UniversalClient{}).Run(context.Background(), request) + if err != nil { + t.Fatalf("run failed: %v", err) + } + data, ok := response.Result["data"].([]any) + if !ok || len(data) != 1 { + t.Fatalf("unexpected nested result: %#v", response.Result) + } + image, ok := data[0].(map[string]any) + if !ok || image["url"] != "https://cdn.example/hello-hello.png" { + t.Fatalf("unexpected image result: %#v", response.Result) + } +} + func TestUniversalClientResumeSkipsSubmit(t *testing.T) { request := Request{ Kind: "videos.generations",