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
3e5bc637
authored
Aug 26, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: Invalid type for 'input[x].summary': expected an array of objects, but got null instead
parent
f249cf9a
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
53 additions
and
8 deletions
+53
-8
common/json.go
+22
-0
dto/openai_request.go
+21
-6
relay/channel/openai/adaptor.go
+7
-1
relay/channel/openai/relay_responses.go
+2
-0
relay/common/relay_info.go
+1
-1
No files found.
common/json.go
View file @
3e5bc637
...
...
@@ -20,3 +20,25 @@ func DecodeJson(reader *bytes.Reader, v any) error {
func
Marshal
(
v
any
)
([]
byte
,
error
)
{
return
json
.
Marshal
(
v
)
}
func
GetJsonType
(
data
json
.
RawMessage
)
string
{
data
=
bytes
.
TrimSpace
(
data
)
if
len
(
data
)
==
0
{
return
"unknown"
}
firstChar
:=
bytes
.
TrimSpace
(
data
)[
0
]
switch
firstChar
{
case
'{'
:
return
"object"
case
'['
:
return
"array"
case
'"'
:
return
"string"
case
't'
,
'f'
:
return
"boolean"
case
'n'
:
return
"null"
default
:
return
"number"
}
}
dto/openai_request.go
View file @
3e5bc637
...
...
@@ -761,7 +761,7 @@ type WebSearchOptions struct {
// https://platform.openai.com/docs/api-reference/responses/create
type
OpenAIResponsesRequest
struct
{
Model
string
`json:"model"`
Input
any
`json:"input,omitempty"`
Input
json
.
RawMessage
`json:"input,omitempty"`
Include
json
.
RawMessage
`json:"include,omitempty"`
Instructions
json
.
RawMessage
`json:"instructions,omitempty"`
MaxOutputTokens
uint
`json:"max_output_tokens,omitempty"`
...
...
@@ -775,7 +775,7 @@ type OpenAIResponsesRequest struct {
Temperature
float64
`json:"temperature,omitempty"`
Text
json
.
RawMessage
`json:"text,omitempty"`
ToolChoice
json
.
RawMessage
`json:"tool_choice,omitempty"`
Tools
[]
map
[
string
]
any
`json:"tools,omitempty"`
// 需要处理的参数很少,MCP 参数太多不确定,所以用 map
Tools
json
.
RawMessage
`json:"tools,omitempty"`
// 需要处理的参数很少,MCP 参数太多不确定,所以用 map
TopP
float64
`json:"top_p,omitempty"`
Truncation
string
`json:"truncation,omitempty"`
User
string
`json:"user,omitempty"`
...
...
@@ -832,8 +832,7 @@ func (r *OpenAIResponsesRequest) GetTokenCountMeta() *types.TokenCountMeta {
}
if
len
(
r
.
Tools
)
>
0
{
toolStr
,
_
:=
common
.
Marshal
(
r
.
Tools
)
texts
=
append
(
texts
,
string
(
toolStr
))
texts
=
append
(
texts
,
string
(
r
.
Tools
))
}
return
&
types
.
TokenCountMeta
{
...
...
@@ -853,6 +852,14 @@ func (r *OpenAIResponsesRequest) SetModelName(modelName string) {
}
}
func
(
r
*
OpenAIResponsesRequest
)
GetToolsMap
()
[]
map
[
string
]
any
{
var
toolsMap
[]
map
[
string
]
any
if
len
(
r
.
Tools
)
>
0
{
_
=
common
.
Unmarshal
(
r
.
Tools
,
&
toolsMap
)
}
return
toolsMap
}
type
Reasoning
struct
{
Effort
string
`json:"effort,omitempty"`
Summary
string
`json:"summary,omitempty"`
...
...
@@ -879,13 +886,21 @@ func (r *OpenAIResponsesRequest) ParseInput() []MediaInput {
var
inputs
[]
MediaInput
// Try string first
if
str
,
ok
:=
r
.
Input
.
(
string
);
ok
{
// if str, ok := common.GetJsonType(r.Input); ok {
// inputs = append(inputs, MediaInput{Type: "input_text", Text: str})
// return inputs
// }
if
common
.
GetJsonType
(
r
.
Input
)
==
"string"
{
var
str
string
_
=
common
.
Unmarshal
(
r
.
Input
,
&
str
)
inputs
=
append
(
inputs
,
MediaInput
{
Type
:
"input_text"
,
Text
:
str
})
return
inputs
}
// Try array of parts
if
array
,
ok
:=
r
.
Input
.
([]
any
);
ok
{
if
common
.
GetJsonType
(
r
.
Input
)
==
"array"
{
var
array
[]
any
_
=
common
.
Unmarshal
(
r
.
Input
,
&
array
)
for
_
,
itemAny
:=
range
array
{
// Already parsed MediaInput
if
media
,
ok
:=
itemAny
.
(
MediaInput
);
ok
{
...
...
relay/channel/openai/adaptor.go
View file @
3e5bc637
...
...
@@ -537,8 +537,14 @@ func detectImageMimeType(filename string) string {
func
(
a
*
Adaptor
)
ConvertOpenAIResponsesRequest
(
c
*
gin
.
Context
,
info
*
relaycommon
.
RelayInfo
,
request
dto
.
OpenAIResponsesRequest
)
(
any
,
error
)
{
// 转换模型推理力度后缀
effort
,
originModel
:=
parseReasoningEffortFromModelSuffix
(
request
.
Model
)
if
effort
!=
""
&&
request
.
Reasoning
!=
nil
{
if
effort
!=
""
{
if
request
.
Reasoning
==
nil
{
request
.
Reasoning
=
&
dto
.
Reasoning
{
Effort
:
effort
,
}
}
else
{
request
.
Reasoning
.
Effort
=
effort
}
request
.
Model
=
originModel
}
return
request
,
nil
...
...
relay/channel/openai/relay_responses.go
View file @
3e5bc637
...
...
@@ -92,6 +92,8 @@ func OaiResponsesStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp
}
}
}
}
else
{
logger
.
LogError
(
c
,
"failed to unmarshal stream response: "
+
err
.
Error
())
}
return
true
})
...
...
relay/common/relay_info.go
View file @
3e5bc637
...
...
@@ -313,7 +313,7 @@ func GenRelayInfoResponses(c *gin.Context, request *dto.OpenAIResponsesRequest)
BuiltInTools
:
make
(
map
[
string
]
*
BuildInToolInfo
),
}
if
len
(
request
.
Tools
)
>
0
{
for
_
,
tool
:=
range
request
.
Tools
{
for
_
,
tool
:=
range
request
.
GetToolsMap
()
{
toolType
:=
common
.
Interface2String
(
tool
[
"type"
])
info
.
ResponsesUsageInfo
.
BuiltInTools
[
toolType
]
=
&
BuildInToolInfo
{
ToolName
:
toolType
,
...
...
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