Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4e5c6297
authored
Dec 09, 2025
by
Calcium-Ion
Committed by
GitHub
Dec 09, 2025
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2356 from seefs001/feature/zhipiu_4v_image
feat: zhipu 4v image generations
parents
52c9e0ed
634651b4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
4 deletions
+138
-4
dto/openai_image.go
+5
-2
relay/channel/zhipu_4v/adaptor.go
+6
-2
relay/channel/zhipu_4v/image.go
+127
-0
No files found.
dto/openai_image.go
View file @
4e5c6297
...
@@ -27,8 +27,11 @@ type ImageRequest struct {
...
@@ -27,8 +27,11 @@ type ImageRequest struct {
OutputCompression
json
.
RawMessage
`json:"output_compression,omitempty"`
OutputCompression
json
.
RawMessage
`json:"output_compression,omitempty"`
PartialImages
json
.
RawMessage
`json:"partial_images,omitempty"`
PartialImages
json
.
RawMessage
`json:"partial_images,omitempty"`
// Stream bool `json:"stream,omitempty"`
// Stream bool `json:"stream,omitempty"`
Watermark
*
bool
`json:"watermark,omitempty"`
Watermark
*
bool
`json:"watermark,omitempty"`
Image
json
.
RawMessage
`json:"image,omitempty"`
// zhipu 4v
WatermarkEnabled
json
.
RawMessage
`json:"watermark_enabled,omitempty"`
UserId
json
.
RawMessage
`json:"user_id,omitempty"`
Image
json
.
RawMessage
`json:"image,omitempty"`
// 用匿名参数接收额外参数
// 用匿名参数接收额外参数
Extra
map
[
string
]
json
.
RawMessage
`json:"-"`
Extra
map
[
string
]
json
.
RawMessage
`json:"-"`
}
}
...
...
relay/channel/zhipu_4v/adaptor.go
View file @
4e5c6297
...
@@ -36,8 +36,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
...
@@ -36,8 +36,7 @@ func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInf
}
}
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
func
(
a
*
Adaptor
)
ConvertImageRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
ImageRequest
)
(
any
,
error
)
{
//TODO implement me
return
request
,
nil
return
nil
,
errors
.
New
(
"not implemented"
)
}
}
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
func
(
a
*
Adaptor
)
Init
(
info
*
relaycommon
.
RelayInfo
)
{
...
@@ -63,6 +62,8 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
...
@@ -63,6 +62,8 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
return
fmt
.
Sprintf
(
"%s/embeddings"
,
specialPlan
.
OpenAIBaseURL
),
nil
return
fmt
.
Sprintf
(
"%s/embeddings"
,
specialPlan
.
OpenAIBaseURL
),
nil
}
}
return
fmt
.
Sprintf
(
"%s/api/paas/v4/embeddings"
,
baseURL
),
nil
return
fmt
.
Sprintf
(
"%s/api/paas/v4/embeddings"
,
baseURL
),
nil
case
relayconstant
.
RelayModeImagesGenerations
:
return
fmt
.
Sprintf
(
"%s/api/paas/v4/images/generations"
,
baseURL
),
nil
default
:
default
:
if
hasSpecialPlan
&&
specialPlan
.
OpenAIBaseURL
!=
""
{
if
hasSpecialPlan
&&
specialPlan
.
OpenAIBaseURL
!=
""
{
return
fmt
.
Sprintf
(
"%s/chat/completions"
,
specialPlan
.
OpenAIBaseURL
),
nil
return
fmt
.
Sprintf
(
"%s/chat/completions"
,
specialPlan
.
OpenAIBaseURL
),
nil
...
@@ -114,6 +115,9 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
...
@@ -114,6 +115,9 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
return
claude
.
ClaudeHandler
(
c
,
resp
,
info
,
claude
.
RequestModeMessage
)
return
claude
.
ClaudeHandler
(
c
,
resp
,
info
,
claude
.
RequestModeMessage
)
}
}
default
:
default
:
if
info
.
RelayMode
==
relayconstant
.
RelayModeImagesGenerations
{
return
zhipu4vImageHandler
(
c
,
resp
,
info
)
}
adaptor
:=
openai
.
Adaptor
{}
adaptor
:=
openai
.
Adaptor
{}
return
adaptor
.
DoResponse
(
c
,
resp
,
info
)
return
adaptor
.
DoResponse
(
c
,
resp
,
info
)
}
}
...
...
relay/channel/zhipu_4v/image.go
0 → 100644
View file @
4e5c6297
package
zhipu_4v
import
(
"io"
"net/http"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/logger"
relaycommon
"github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/types"
"github.com/gin-gonic/gin"
)
type
zhipuImageRequest
struct
{
Model
string
`json:"model"`
Prompt
string
`json:"prompt"`
Quality
string
`json:"quality,omitempty"`
Size
string
`json:"size,omitempty"`
WatermarkEnabled
*
bool
`json:"watermark_enabled,omitempty"`
UserID
string
`json:"user_id,omitempty"`
}
type
zhipuImageResponse
struct
{
Created
*
int64
`json:"created,omitempty"`
Data
[]
zhipuImageData
`json:"data,omitempty"`
ContentFilter
any
`json:"content_filter,omitempty"`
Usage
*
dto
.
Usage
`json:"usage,omitempty"`
Error
*
zhipuImageError
`json:"error,omitempty"`
RequestID
string
`json:"request_id,omitempty"`
ExtendParam
map
[
string
]
string
`json:"extendParam,omitempty"`
}
type
zhipuImageError
struct
{
Code
string
`json:"code"`
Message
string
`json:"message"`
}
type
zhipuImageData
struct
{
Url
string
`json:"url,omitempty"`
ImageUrl
string
`json:"image_url,omitempty"`
B64Json
string
`json:"b64_json,omitempty"`
B64Image
string
`json:"b64_image,omitempty"`
}
type
openAIImagePayload
struct
{
Created
int64
`json:"created"`
Data
[]
openAIImageData
`json:"data"`
}
type
openAIImageData
struct
{
B64Json
string
`json:"b64_json"`
}
func
zhipu4vImageHandler
(
c
*
gin
.
Context
,
resp
*
http
.
Response
,
info
*
relaycommon
.
RelayInfo
)
(
*
dto
.
Usage
,
*
types
.
NewAPIError
)
{
responseBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
types
.
NewOpenAIError
(
err
,
types
.
ErrorCodeReadResponseBodyFailed
,
http
.
StatusInternalServerError
)
}
service
.
CloseResponseBodyGracefully
(
resp
)
var
zhipuResp
zhipuImageResponse
if
err
:=
common
.
Unmarshal
(
responseBody
,
&
zhipuResp
);
err
!=
nil
{
return
nil
,
types
.
NewOpenAIError
(
err
,
types
.
ErrorCodeBadResponseBody
,
http
.
StatusInternalServerError
)
}
if
zhipuResp
.
Error
!=
nil
&&
zhipuResp
.
Error
.
Message
!=
""
{
return
nil
,
types
.
WithOpenAIError
(
types
.
OpenAIError
{
Message
:
zhipuResp
.
Error
.
Message
,
Type
:
"zhipu_image_error"
,
Code
:
zhipuResp
.
Error
.
Code
,
},
resp
.
StatusCode
)
}
payload
:=
openAIImagePayload
{}
if
zhipuResp
.
Created
!=
nil
&&
*
zhipuResp
.
Created
!=
0
{
payload
.
Created
=
*
zhipuResp
.
Created
}
else
{
payload
.
Created
=
info
.
StartTime
.
Unix
()
}
for
_
,
data
:=
range
zhipuResp
.
Data
{
url
:=
data
.
Url
if
url
==
""
{
url
=
data
.
ImageUrl
}
if
url
==
""
{
logger
.
LogWarn
(
c
,
"zhipu_image_missing_url"
)
continue
}
var
b64
string
switch
{
case
data
.
B64Json
!=
""
:
b64
=
data
.
B64Json
case
data
.
B64Image
!=
""
:
b64
=
data
.
B64Image
default
:
_
,
downloaded
,
err
:=
service
.
GetImageFromUrl
(
url
)
if
err
!=
nil
{
logger
.
LogError
(
c
,
"zhipu_image_get_b64_failed: "
+
err
.
Error
())
continue
}
b64
=
downloaded
}
if
b64
==
""
{
logger
.
LogWarn
(
c
,
"zhipu_image_empty_b64"
)
continue
}
imageData
:=
openAIImageData
{
B64Json
:
b64
,
}
payload
.
Data
=
append
(
payload
.
Data
,
imageData
)
}
jsonResp
,
err
:=
common
.
Marshal
(
payload
)
if
err
!=
nil
{
return
nil
,
types
.
NewError
(
err
,
types
.
ErrorCodeBadResponseBody
)
}
service
.
IOCopyBytesGracefully
(
c
,
resp
,
jsonResp
)
return
&
dto
.
Usage
{},
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment