Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
3decb33
feat(AliAdaptor): enhance video input structure and add PixVerse support
Fankouzu Apr 9, 2026
f4afb2d
Merge pull request #1 from Fankouzu/custom/pixverse-billing
Fankouzu Apr 9, 2026
9579270
chore(web): bump @lobehub/icons, VisActor vchart, add antd peer
Fankouzu Apr 9, 2026
e321282
Merge pull request #2 from Fankouzu:chore/bump-lobehub-icons-visactor…
Fankouzu Apr 9, 2026
2bfc9c3
fix(doubao): preserve draft_task id in video content items
Fankouzu Apr 11, 2026
3aaedc2
Merge pull request #3 from Fankouzu/feat/doubao-seedance-draft-task-c…
Fankouzu Apr 11, 2026
6162fdb
Merge branch 'QuantumNous:main' into main
Fankouzu Apr 11, 2026
6b33a38
fix(doubao): skip appending prompt text when content uses draft_task
Fankouzu Apr 11, 2026
49a3baa
Merge pull request #4 from Fankouzu/fix/doubao-seedance-draft-no-text…
Fankouzu Apr 11, 2026
137cd7f
Merge upstream/main into main: resolve web deps (keep visactor v2, an…
Fankouzu Apr 15, 2026
4bac883
feat(channel): add PingXingShiJie async task channel (fork of task/do…
Fankouzu Apr 15, 2026
80a1ef3
feat(pingxingshijie): align channel 58 with /v2 APIs, envelope, and a…
Fankouzu Apr 15, 2026
fe9ea68
fix(relay): use Distribute relay_mode for GET /v1/images/generations/…
Fankouzu Apr 15, 2026
f1fb6f0
fix(pingxingshijie): map image task done status and data[].url for Se…
Fankouzu Apr 15, 2026
8809ba3
fix(task): image result_url recovery, upstream_kind in API, admin ima…
Fankouzu Apr 15, 2026
0328b85
fix(relay): accept image field as string or URL array in TaskSubmitReq
Fankouzu Apr 15, 2026
9fa4128
fix(pingxingshijie): avoid empty envelope data breaking ConvertToOpen…
Fankouzu Apr 15, 2026
49ba8f5
feat(pingxingshijie): pass full upstream JSON via metadata.upstream /…
Fankouzu Apr 15, 2026
35cbcb0
fix(pingxingshijie): extract video create task id from task_id and ne…
Fankouzu Apr 15, 2026
0771812
fix(pingxingshijie): Seedance 1.5 Pro draft_task upscale forwarding a…
Fankouzu Apr 16, 2026
ee071b8
Merge pull request #5 from Fankouzu/feature/channel-pingxingshijie-task
Fankouzu Apr 16, 2026
cb72e2e
feat(pingxingshijie): map channel 58 to Volc relay for chat, unwrap e…
Fankouzu Apr 16, 2026
7288053
fix(pingxingshijie): use /v1/chat/completions upstream for channel 58…
Fankouzu Apr 16, 2026
d077cd7
fix(pingxingshijie): update upstream path for channel 58 to /v2/chat/…
Fankouzu Apr 16, 2026
f4b3c52
Merge pull request #6 from Fankouzu/feature/pingxingshijie-text-chann…
Fankouzu Apr 17, 2026
9f26d60
Merge upstream/main
Fankouzu Apr 28, 2026
1ee1935
Merge origin/main
Fankouzu Apr 28, 2026
8caca48
feat: add comprehensive Token Management API reference documentation
Fankouzu Apr 28, 2026
e89b74c
feat: add Kie task adaptor
Fankouzu Apr 28, 2026
cd369ae
feat: register Kie channel type
Fankouzu Apr 28, 2026
2deeaf9
feat: wire Kie task relay
Fankouzu Apr 28, 2026
490e869
feat: expose Kie models in registry
Fankouzu Apr 28, 2026
ab34e53
feat: add Kie channel option
Fankouzu Apr 28, 2026
e6a6b51
feat: add Kie channel logo
Fankouzu Apr 29, 2026
9965d31
fix: stabilize task billing ratios
Fankouzu Apr 30, 2026
6105339
fix: preserve task provider metadata
Fankouzu Apr 30, 2026
ed4cc98
fix: sync PingXingShiJie task adapter
Fankouzu Apr 30, 2026
cdece92
fix: align PingXingShiJie image endpoint
Fankouzu Apr 30, 2026
0d5f32b
fix: scale Kie image billing by resolution
Fankouzu Apr 30, 2026
63f898e
fix: preserve task request metadata fields
Fankouzu Apr 30, 2026
cf2ac39
Merge pull request #7 from Fankouzu/sync/pingxingshijie-upstream
Fankouzu Apr 30, 2026
9a7e171
Merge origin/main into feature/kie-ai-channel
Fankouzu Apr 30, 2026
56db688
Merge pull request #8 from Fankouzu/feature/kie-ai-channel
Fankouzu Apr 30, 2026
9927a1f
Merge upstream/main into main
Fankouzu Apr 30, 2026
03064d2
fix(ui): add default channel labels for PingXingShiJie and KieAI
Fankouzu Apr 30, 2026
699b7f0
fix(ui): render external channel logo URLs
Fankouzu Apr 30, 2026
c1faa38
Merge pull request #9 from Fankouzu/fix/default-channel-58-59-logos
Fankouzu Apr 30, 2026
08d6d03
feat(logs): extract task media results
Fankouzu Apr 30, 2026
a53db1f
feat(logs): add task media results dialog
Fankouzu Apr 30, 2026
b925361
feat(logs): show task media results in table
Fankouzu Apr 30, 2026
4e1ca77
feat(i18n): add task media result labels
Fankouzu Apr 30, 2026
f039ab0
feat(i18n): add task media result translations
Fankouzu Apr 30, 2026
620aea3
Merge pull request #10 from Fankouzu/feat/default-task-media-results
Fankouzu Apr 30, 2026
ccb29df
feat(distributor): update default model to use taskpxsj.AssetPlacehol…
Fankouzu May 1, 2026
da05d30
fix(distributor): require asset upload model
Fankouzu May 1, 2026
d6990a8
fix(pingxingshijie): validate asset upload model
Fankouzu May 1, 2026
e9044ab
fix(logs): label asset upload tasks
Fankouzu May 1, 2026
e5d0307
docs(pingxingshijie): require asset upload model
Fankouzu May 1, 2026
6f4e325
fix(pingxingshijie): strip asset upload gateway model
Fankouzu May 1, 2026
a0abb43
docs(pingxingshijie): clarify asset upload forwarding
Fankouzu May 1, 2026
86b5783
fix(pingxingshijie): store asset uploads with asset action
Fankouzu May 1, 2026
a39fcea
fix(logs): recognize asset upload action
Fankouzu May 1, 2026
7918ee2
fix(classic): label asset upload task logs
Fankouzu May 1, 2026
37c7e49
fix(classic): skip compressed size reporting
Fankouzu May 1, 2026
cb50bca
feat(pingxingshijie): support asset_id lookup for GET /v1/assets/:ass…
Fankouzu May 1, 2026
60f42c2
docs(pingxingshijie): update asset query to use asset_id path param
Fankouzu May 1, 2026
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ data/
.gomodcache/
.gocache-temp
.gopath
.test
token_estimator_test.go
# Local copy of vendor API doc; not tracked (example URLs may trip GitHub push protection)
Pingxingshijie-AI接口.md
.test
skills-lock.json
6 changes: 6 additions & 0 deletions common/api_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ func ChannelType2APIType(channelType int) (int, bool) {
apiType = constant.APITypeMokaAI
case constant.ChannelTypeVolcEngine:
apiType = constant.APITypeVolcEngine
case constant.ChannelTypePingXingShiJie:
// Text/embed/rerank/image sync: same HTTP paths as Volcengine Ark (/api/v3/*). Async tasks still use task/pingxingshijie.
apiType = constant.APITypeVolcEngine
case constant.ChannelTypeKieAI:
// KieAI currently exposes async Market jobs through task/kie; sync calls fall back to OpenAI-compatible handling when used.
apiType = constant.APITypeOpenAI
case constant.ChannelTypeBaiduV2:
apiType = constant.APITypeBaiduV2
case constant.ChannelTypeOpenRouter:
Expand Down
6 changes: 6 additions & 0 deletions constant/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const (
ChannelTypeSora = 55
ChannelTypeReplicate = 56
ChannelTypeCodex = 57
ChannelTypePingXingShiJie = 58
ChannelTypeKieAI = 59
ChannelTypeDummy // this one is only for count, do not add any channel after this

)
Expand Down Expand Up @@ -118,6 +120,8 @@ var ChannelBaseURLs = []string{
"https://api.openai.com", //55
"https://api.replicate.com", //56
"https://chatgpt.com", //57
"https://api.pingxingshijie.cn", //58 PingXingShiJie
"https://api.kie.ai", //59 KieAI
}

var ChannelTypeNames = map[int]string{
Expand Down Expand Up @@ -175,6 +179,8 @@ var ChannelTypeNames = map[int]string{
ChannelTypeSora: "Sora",
ChannelTypeReplicate: "Replicate",
ChannelTypeCodex: "Codex",
ChannelTypePingXingShiJie: "PingXingShiJie",
ChannelTypeKieAI: "KieAI",
}

func GetChannelTypeName(channelType int) string {
Expand Down
3 changes: 2 additions & 1 deletion constant/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ type TaskPlatform string

const (
TaskPlatformSuno TaskPlatform = "suno"
TaskPlatformMidjourney = "mj"
TaskPlatformMidjourney TaskPlatform = "mj"
)

const (
SunoActionMusic = "MUSIC"
SunoActionLyrics = "LYRICS"

TaskActionGenerate = "generate"
TaskActionAssetUpload = "assetUpload"
TaskActionTextGenerate = "textGenerate"
TaskActionFirstTailGenerate = "firstTailGenerate"
TaskActionReferenceGenerate = "referenceGenerate"
Expand Down
5 changes: 5 additions & 0 deletions controller/channel-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
requestPath = "/v1/images/generations"
}

// PingXingShiJie: sync image models use OpenAI image relay; text uses chat (Volc-style upstream via adaptor mapping).
if channel.Type == constant.ChannelTypePingXingShiJie && strings.Contains(strings.ToLower(testModel), "seedream") {
requestPath = "/v1/images/generations"
}
Comment on lines +125 to +128

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep endpoint type in sync when forcing PingXing image test path.

Line 125-128 switches requestPath to /v1/images/generations, but endpointType stays empty, so buildTestRequest(...) can still build a non-image request and later fail image conversion (invalid image request type).

🔧 Proposed fix
-		// VolcEngine 图像生成模型
-		if channel.Type == constant.ChannelTypeVolcEngine && strings.Contains(testModel, "seedream") {
-			requestPath = "/v1/images/generations"
-		}
-
-		// PingXingShiJie: sync image models use OpenAI image relay; text uses chat (Volc-style upstream via adaptor mapping).
-		if channel.Type == constant.ChannelTypePingXingShiJie && strings.Contains(strings.ToLower(testModel), "seedream") {
-			requestPath = "/v1/images/generations"
-		}
+		// Seedream image models should use OpenAI image endpoint and image request payload.
+		lowerModel := strings.ToLower(testModel)
+		if strings.Contains(lowerModel, "seedream") &&
+			(channel.Type == constant.ChannelTypeVolcEngine || channel.Type == constant.ChannelTypePingXingShiJie) {
+			requestPath = "/v1/images/generations"
+			endpointType = string(constant.EndpointTypeImageGeneration)
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controller/channel-test.go` around lines 125 - 128, When forcing the
PingXingShiJie image test path you set requestPath but forgot to set
endpointType, causing buildTestRequest(...) to produce a non-image request;
update the branch that checks channel.Type == constant.ChannelTypePingXingShiJie
&& strings.Contains(strings.ToLower(testModel), "seedream") to also set
endpointType to the image type used by your request (e.g., the image/images
enum/value your code expects) so buildTestRequest(...) builds an image request
and image conversion won't fail.


// responses-only models
if strings.Contains(strings.ToLower(testModel), "codex") {
requestPath = "/v1/responses"
Expand Down
18 changes: 18 additions & 0 deletions controller/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/QuantumNous/new-api/relay/channel/lingyiwanwu"
"github.com/QuantumNous/new-api/relay/channel/minimax"
"github.com/QuantumNous/new-api/relay/channel/moonshot"
taskkie "github.com/QuantumNous/new-api/relay/channel/task/kie"
taskpxsj "github.com/QuantumNous/new-api/relay/channel/task/pingxingshijie"
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/relay/helper"
"github.com/QuantumNous/new-api/service"
Expand Down Expand Up @@ -79,6 +81,14 @@ func init() {
OwnedBy: minimax.ChannelName,
})
}
for _, modelName := range taskkie.ModelList {
openAIModels = append(openAIModels, dto.OpenAIModels{
Id: modelName,
Object: "model",
Created: 1626777600,
OwnedBy: taskkie.ChannelName,
})
}
for modelName, _ := range constant.MidjourneyModel2Action {
openAIModels = append(openAIModels, dto.OpenAIModels{
Id: modelName,
Expand All @@ -93,6 +103,14 @@ func init() {
}
channelId2Models = make(map[int][]string)
for i := 1; i <= constant.ChannelTypeDummy; i++ {
if i == constant.ChannelTypePingXingShiJie {
channelId2Models[i] = append([]string(nil), taskpxsj.ModelList...)
continue
}
if i == constant.ChannelTypeKieAI {
channelId2Models[i] = append([]string(nil), taskkie.ModelList...)
continue
}
apiType, success := common.ChannelType2APIType(i)
if !success || apiType == constant.APITypeAIProxyLibrary {
continue
Expand Down
9 changes: 9 additions & 0 deletions controller/model_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/model"
taskkie "github.com/QuantumNous/new-api/relay/channel/task/kie"
"github.com/QuantumNous/new-api/setting/config"
"github.com/QuantumNous/new-api/setting/operation_setting"
"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -210,6 +211,14 @@ func TestListModelsIncludesTieredBillingModel(t *testing.T) {
require.Empty(t, missingExprPricing.BillingExpr)
}

func TestKieModelsAppearInGlobalModelRegistry(t *testing.T) {
for _, modelName := range taskkie.ModelList {
aiModel, ok := openAIModelsMap[modelName]
require.True(t, ok, "missing Kie model %s", modelName)
require.Equal(t, taskkie.ChannelName, aiModel.OwnedBy)
}
}

func TestListModelsTokenLimitIncludesTieredBillingModel(t *testing.T) {
withSelfUseModeDisabled(t)
withTieredBillingConfig(t, map[string]string{
Expand Down
2 changes: 2 additions & 0 deletions controller/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
relaycommon "github.com/QuantumNous/new-api/relay/common"
relayconstant "github.com/QuantumNous/new-api/relay/constant"
"github.com/QuantumNous/new-api/relay/helper"
taskpxsj "github.com/QuantumNous/new-api/relay/channel/task/pingxingshijie"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/setting"
"github.com/QuantumNous/new-api/setting/operation_setting"
Expand Down Expand Up @@ -572,6 +573,7 @@ func RelayTask(c *gin.Context) {

task := model.InitTask(result.Platform, relayInfo)
task.PrivateData.UpstreamTaskID = result.UpstreamTaskID
task.PrivateData.UpstreamKind = taskpxsj.UpstreamKindFromPath(c.Request.URL.Path)
task.PrivateData.BillingSource = relayInfo.BillingSource
task.PrivateData.SubscriptionId = relayInfo.SubscriptionId
task.PrivateData.TokenId = relayInfo.TokenId
Expand Down
Loading