Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/patches.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,35 @@ This file tracks patches deployed in this fork before they are accepted upstream
| Patch | Status | Source | Imported Branch | Deployment Branch | Data Impact | Rollback |
| --- | --- | --- | --- | --- | --- | --- |
| PR 4810 - Ali wan2.7 and HappyHorse video support | `Deployed` | https://github.com/QuantumNous/new-api/pull/4810 | `vendor/pr-4810` + `compat/pr-4810` | `deploy/main` | No patch-specific migration; task-plugin usage and billing configuration change | Revert the compatibility merge to restore the official Alibaba plugin; no data cleanup expected |
| Wan 2.7 image generation protocol guard | `Proposed` | Local fix for desirecore/desirecore#3522 | `codex/wan27-image-route-rc33` | `codex/release-rc33` candidate | No schema migration; two exact model IDs ignore stale `qwen.sync_image_models` when selecting image protocol | Revert the scoped fix; the persisted setting remains unchanged |

## Patch Entries

### Wan 2.7 image generation protocol guard

- Status: `Proposed`; not merged or deployed.
- Source: local fix for https://github.com/desirecore/desirecore/issues/3522, commit `39b1b0b`.
- Patch branch: `codex/wan27-image-route-rc33`.
- Candidate branch: `codex/release-rc33`; production branch `deploy/main` remains unchanged.
- Owner: desirecore.

#### Purpose and evidence

The candidate's `Ali` image adaptor chooses the legacy `text2image/image-synthesis` endpoint when a persisted `qwen.sync_image_models` list from before Wan 2.7 omits these model IDs. Alibaba documents Wan 2.7 synchronous image generation at `multimodal-generation/generation`. A regression test first reproduced the old endpoint, async header, and prompt-only body under that persisted-list fixture; the patch makes both exact Wan 2.7 image IDs use the documented synchronous protocol. The live gateway's actual setting and selected channel remain unverified, so this patch is a targeted candidate, not proof that issue #3522 is resolved.

#### Data compatibility and rollback

- No database, migration, log schema, API response, or billing change.
- Existing `qwen.sync_image_models` data is preserved. Only `wan2.7-image` and `wan2.7-image-pro` bypass a stale list for image generation routing.
- Revert the scoped commit to restore previous behavior; no data cleanup is needed. Do not promote before testing against a representative copy of the gateway configuration and performing real requests to both models.
- Compare a future official upstream fix to this exact-model guard, then remove the local delta once the official behavior is verified.

#### Verification

- `go test ./relay/channel/ali -count=1` passed on the rc.33 candidate branch.
- Real model generation through a candidate image has not yet been tested; production deployment has not occurred.


### PR 4810 - Ali wan2.7 and HappyHorse video support

- Status: `Deployed`
Expand Down
5 changes: 4 additions & 1 deletion docs/release-rc33.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
- Candidate branch: `codex/release-rc33`.
- Intended fork version: `v1.0.0-rc.33-desirecore.1`.
- Production predecessor: `v1.0.0-rc.30-desirecore.2` at `f98e7b6b44d5a2f1bcd1932d5576fc6e5215bcc4`.
- Only imported runtime delta: PR 4810 Alibaba compatibility commits `f6520a996` and `7d7cf46e7`, cherry-picked with provenance as `b7b3a10f5` and `3ba267dd3`. Plugin code and its original tests are identical to the production predecessor.
- Imported runtime delta: PR 4810 Alibaba compatibility commits `f6520a996` and `7d7cf46e7`, cherry-picked with provenance as `b7b3a10f5` and `3ba267dd3`. Plugin code and its original tests are identical to the production predecessor.
- Proposed additional candidate delta: exact-model Wan 2.7 image generation routing guard for stale persisted `qwen.sync_image_models`; see `docs/patches.md`. This has not been merged into the tested image or deployed.
- Other fork changes: maintenance rules, patch register, this handoff, manual GHCR/Tencent publishing workflow, exclusions for fork tags in official publishing workflows, and a focused Qwen Claude regression test.
- Official rc.33 is a prerelease and its release notes do not recommend production use. This candidate is for acceptance testing first.

Expand All @@ -18,6 +19,7 @@
- In `relaykit/`, `GOWORK=off go test ./...` and `GOWORK=off go build ./...`: passed.
- `TEST_MYSQL_DSN='<isolated MySQL DSN>' TEST_POSTGRES_DSN='<isolated PostgreSQL DSN>' go test ./model -count=1`: passed against local disposable MySQL 8.0.46 and PostgreSQL 15.18, plus embedded SQLite 3.50.4. Ports: 127.0.0.1:13316 and 127.0.0.1:15436; database: `newapi_test`. Test credentials are local fixtures, not production credentials.
- Compared schema/model definitions, startup migration code, and Go dependencies with the production predecessor: no changes. Two model files change routing-name normalization only.
- For the proposed Wan 2.7 image guard: `go test ./relay/channel/ali -count=1` passed on a branch based on this rc.33 candidate. Its regression test first failed under a simulated old persisted sync-model list, then passed with the scoped fix. This does not verify the live gateway setting or image generation.

## Operator Acceptance Required

Expand All @@ -29,5 +31,6 @@ Image publication is not deployment rehearsal. The following have NOT been perfo
4. Verify Alibaba video creation, historical task polling, results, decimal durations, pre-consume, settlement and failure refunds. Check both JSON and multipart requests and current prices.
5. Rehearse rollback against the upgraded test database and configuration. Do not assume an older image alone is sufficient; restoring a snapshot after new writes requires reconciliation.
6. Record operator results, exact tested image digest and acceptance before production promotion. Keep production `deploy/main` and the existing release tags unchanged until acceptance.
7. If the proposed Wan 2.7 image guard is included, inspect the candidate's effective Alibaba channel type, upstream model mapping, base URL and persisted `qwen.sync_image_models`. Then call `wan2.7-image` and `wan2.7-image-pro` through `/v1/images/generations` and verify actual image output. The same HTTP 400 can have other gateway configuration causes; the local regression test alone cannot close issue #3522.

Publish candidate images under a `test-` tag prefix. Record the immutable build SHA and digest from the workflow run in the acceptance record; do not deploy an unverified rebuilt image under the same version.
6 changes: 6 additions & 0 deletions relay/channel/ali/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ var syncModels = []string{
}

func isSyncImageModel(modelName string) bool {
// Wan 2.7 generation uses the multimodal endpoint even when an older
// persisted sync_image_models setting has not gained these model IDs.
// https://help.aliyun.com/zh/model-studio/wan-image-generation-and-editing-api-reference
if modelName == "wan2.7-image" || modelName == "wan2.7-image-pro" {
return true
}
return model_setting.IsSyncImageModel(modelName)
}

Expand Down
41 changes: 41 additions & 0 deletions relay/channel/ali/adaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
relayhelper "github.com/QuantumNous/new-api/relay/helper"
"github.com/QuantumNous/new-api/relaykit/dto"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/setting/model_setting"
"github.com/QuantumNous/new-api/setting/system_setting"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -169,6 +170,46 @@ func TestMappedAliImageModelUsesUpstreamProtocol(t *testing.T) {
assert.IsType(t, &AliImageRequest{}, converted)
}

func TestWan27ImageGenerationUsesMultimodalEndpointAfterStoredSyncListUpgrade(t *testing.T) {
settings := model_setting.GetQwenSettings()
previous := settings.SyncImageModels
settings.SyncImageModels = []string{"z-image", "qwen-image", "wan2.6"}
t.Cleanup(func() { settings.SyncImageModels = previous })

for _, model := range []string{"wan2.7-image", "wan2.7-image-pro"} {
t.Run(model, func(t *testing.T) {
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest(http.MethodPost, "/v1/images/generations", nil)
info := &relaycommon.RelayInfo{
RelayMode: constant.RelayModeImagesGenerations,
ChannelMeta: &relaycommon.ChannelMeta{
ChannelBaseUrl: "https://dashscope.aliyuncs.com",
UpstreamModelName: model,
},
}
adaptor := &Adaptor{}
url, err := adaptor.GetRequestURL(info)
require.NoError(t, err)
assert.Equal(t, "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation", url)

header := http.Header{}
require.NoError(t, adaptor.SetupRequestHeader(c, &header, info))
assert.Empty(t, header.Get("X-DashScope-Async"))

converted, err := adaptor.ConvertImageRequest(c, info, dto.ImageRequest{Model: model, Prompt: "portrait"})
require.NoError(t, err)
assert.True(t, adaptor.IsSyncImageModel)
request, ok := converted.(*AliImageRequest)
require.True(t, ok)
input, ok := request.Input.(AliImageInput)
require.True(t, ok)
require.Len(t, input.Messages, 1)
assert.Equal(t, "user", input.Messages[0].Role)
assert.Equal(t, []AliMediaContent{{Text: "portrait"}}, input.Messages[0].Content)
})
}
}

func TestAliImageHandlerHonorsRequestResponseFormat(t *testing.T) {
imageBytes := []byte("ali-image")
var downloads atomic.Int32
Expand Down
Loading