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
4746b2bf
authored
Feb 19, 2026
by
Seefs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add missing OpenAI/Claude/Gemini request fields and responses stream options
parent
d45cd9af
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
1 deletions
+63
-1
dto/channel_settings.go
+1
-0
dto/claude.go
+2
-0
dto/gemini.go
+5
-0
dto/openai_request.go
+11
-0
relay/common/relay_info.go
+17
-0
web/src/components/table/channels/modals/EditChannelModal.jsx
+27
-1
No files found.
dto/channel_settings.go
View file @
4746b2bf
...
@@ -31,6 +31,7 @@ type ChannelOtherSettings struct {
...
@@ -31,6 +31,7 @@ type ChannelOtherSettings struct {
AllowServiceTier
bool
`json:"allow_service_tier,omitempty"`
// 是否允许 service_tier 透传(默认过滤以避免额外计费)
AllowServiceTier
bool
`json:"allow_service_tier,omitempty"`
// 是否允许 service_tier 透传(默认过滤以避免额外计费)
DisableStore
bool
`json:"disable_store,omitempty"`
// 是否禁用 store 透传(默认允许透传,禁用后可能导致 Codex 无法使用)
DisableStore
bool
`json:"disable_store,omitempty"`
// 是否禁用 store 透传(默认允许透传,禁用后可能导致 Codex 无法使用)
AllowSafetyIdentifier
bool
`json:"allow_safety_identifier,omitempty"`
// 是否允许 safety_identifier 透传(默认过滤以保护用户隐私)
AllowSafetyIdentifier
bool
`json:"allow_safety_identifier,omitempty"`
// 是否允许 safety_identifier 透传(默认过滤以保护用户隐私)
AllowIncludeObfuscation
bool
`json:"allow_include_obfuscation,omitempty"`
// 是否允许 stream_options.include_obfuscation 透传(默认过滤以避免关闭流混淆保护)
AwsKeyType
AwsKeyType
`json:"aws_key_type,omitempty"`
AwsKeyType
AwsKeyType
`json:"aws_key_type,omitempty"`
}
}
...
...
dto/claude.go
View file @
4746b2bf
...
@@ -194,6 +194,8 @@ type ClaudeRequest struct {
...
@@ -194,6 +194,8 @@ type ClaudeRequest struct {
Prompt
string
`json:"prompt,omitempty"`
Prompt
string
`json:"prompt,omitempty"`
System
any
`json:"system,omitempty"`
System
any
`json:"system,omitempty"`
Messages
[]
ClaudeMessage
`json:"messages,omitempty"`
Messages
[]
ClaudeMessage
`json:"messages,omitempty"`
// https://platform.claude.com/docs/en/build-with-claude/data-residency#inference-geo
// InferenceGeo string `json:"inference_geo,omitempty"`
MaxTokens
uint
`json:"max_tokens,omitempty"`
MaxTokens
uint
`json:"max_tokens,omitempty"`
MaxTokensToSample
uint
`json:"max_tokens_to_sample,omitempty"`
MaxTokensToSample
uint
`json:"max_tokens_to_sample,omitempty"`
StopSequences
[]
string
`json:"stop_sequences,omitempty"`
StopSequences
[]
string
`json:"stop_sequences,omitempty"`
...
...
dto/gemini.go
View file @
4746b2bf
...
@@ -337,6 +337,7 @@ type GeminiChatGenerationConfig struct {
...
@@ -337,6 +337,7 @@ type GeminiChatGenerationConfig struct {
FrequencyPenalty
*
float32
`json:"frequencyPenalty,omitempty"`
FrequencyPenalty
*
float32
`json:"frequencyPenalty,omitempty"`
ResponseLogprobs
bool
`json:"responseLogprobs,omitempty"`
ResponseLogprobs
bool
`json:"responseLogprobs,omitempty"`
Logprobs
*
int32
`json:"logprobs,omitempty"`
Logprobs
*
int32
`json:"logprobs,omitempty"`
EnableEnhancedCivicAnswers
*
bool
`json:"enableEnhancedCivicAnswers,omitempty"`
MediaResolution
MediaResolution
`json:"mediaResolution,omitempty"`
MediaResolution
MediaResolution
`json:"mediaResolution,omitempty"`
Seed
int64
`json:"seed,omitempty"`
Seed
int64
`json:"seed,omitempty"`
ResponseModalities
[]
string
`json:"responseModalities,omitempty"`
ResponseModalities
[]
string
`json:"responseModalities,omitempty"`
...
@@ -361,6 +362,7 @@ func (c *GeminiChatGenerationConfig) UnmarshalJSON(data []byte) error {
...
@@ -361,6 +362,7 @@ func (c *GeminiChatGenerationConfig) UnmarshalJSON(data []byte) error {
PresencePenaltySnake
*
float32
`json:"presence_penalty,omitempty"`
PresencePenaltySnake
*
float32
`json:"presence_penalty,omitempty"`
FrequencyPenaltySnake
*
float32
`json:"frequency_penalty,omitempty"`
FrequencyPenaltySnake
*
float32
`json:"frequency_penalty,omitempty"`
ResponseLogprobsSnake
bool
`json:"response_logprobs,omitempty"`
ResponseLogprobsSnake
bool
`json:"response_logprobs,omitempty"`
EnableEnhancedCivicAnswersSnake
*
bool
`json:"enable_enhanced_civic_answers,omitempty"`
MediaResolutionSnake
MediaResolution
`json:"media_resolution,omitempty"`
MediaResolutionSnake
MediaResolution
`json:"media_resolution,omitempty"`
ResponseModalitiesSnake
[]
string
`json:"response_modalities,omitempty"`
ResponseModalitiesSnake
[]
string
`json:"response_modalities,omitempty"`
ThinkingConfigSnake
*
GeminiThinkingConfig
`json:"thinking_config,omitempty"`
ThinkingConfigSnake
*
GeminiThinkingConfig
`json:"thinking_config,omitempty"`
...
@@ -408,6 +410,9 @@ func (c *GeminiChatGenerationConfig) UnmarshalJSON(data []byte) error {
...
@@ -408,6 +410,9 @@ func (c *GeminiChatGenerationConfig) UnmarshalJSON(data []byte) error {
if
aux
.
ResponseLogprobsSnake
{
if
aux
.
ResponseLogprobsSnake
{
c
.
ResponseLogprobs
=
aux
.
ResponseLogprobsSnake
c
.
ResponseLogprobs
=
aux
.
ResponseLogprobsSnake
}
}
if
aux
.
EnableEnhancedCivicAnswersSnake
!=
nil
{
c
.
EnableEnhancedCivicAnswers
=
aux
.
EnableEnhancedCivicAnswersSnake
}
if
aux
.
MediaResolutionSnake
!=
""
{
if
aux
.
MediaResolutionSnake
!=
""
{
c
.
MediaResolution
=
aux
.
MediaResolutionSnake
c
.
MediaResolution
=
aux
.
MediaResolutionSnake
}
}
...
...
dto/openai_request.go
View file @
4746b2bf
...
@@ -54,7 +54,9 @@ type GeneralOpenAIRequest struct {
...
@@ -54,7 +54,9 @@ type GeneralOpenAIRequest struct {
ParallelTooCalls
*
bool
`json:"parallel_tool_calls,omitempty"`
ParallelTooCalls
*
bool
`json:"parallel_tool_calls,omitempty"`
Tools
[]
ToolCallRequest
`json:"tools,omitempty"`
Tools
[]
ToolCallRequest
`json:"tools,omitempty"`
ToolChoice
any
`json:"tool_choice,omitempty"`
ToolChoice
any
`json:"tool_choice,omitempty"`
FunctionCall
json
.
RawMessage
`json:"function_call,omitempty"`
User
string
`json:"user,omitempty"`
User
string
`json:"user,omitempty"`
ServiceTier
string
`json:"service_tier,omitempty"`
LogProbs
bool
`json:"logprobs,omitempty"`
LogProbs
bool
`json:"logprobs,omitempty"`
TopLogProbs
int
`json:"top_logprobs,omitempty"`
TopLogProbs
int
`json:"top_logprobs,omitempty"`
Dimensions
int
`json:"dimensions,omitempty"`
Dimensions
int
`json:"dimensions,omitempty"`
...
@@ -261,6 +263,8 @@ type FunctionRequest struct {
...
@@ -261,6 +263,8 @@ type FunctionRequest struct {
type
StreamOptions
struct
{
type
StreamOptions
struct
{
IncludeUsage
bool
`json:"include_usage,omitempty"`
IncludeUsage
bool
`json:"include_usage,omitempty"`
// for /v1/responses
IncludeObfuscation
bool
`json:"include_obfuscation,omitempty"`
}
}
func
(
r
*
GeneralOpenAIRequest
)
GetMaxTokens
()
uint
{
func
(
r
*
GeneralOpenAIRequest
)
GetMaxTokens
()
uint
{
...
@@ -802,8 +806,13 @@ type OpenAIResponsesRequest struct {
...
@@ -802,8 +806,13 @@ type OpenAIResponsesRequest struct {
Model
string
`json:"model"`
Model
string
`json:"model"`
Input
json
.
RawMessage
`json:"input,omitempty"`
Input
json
.
RawMessage
`json:"input,omitempty"`
Include
json
.
RawMessage
`json:"include,omitempty"`
Include
json
.
RawMessage
`json:"include,omitempty"`
// 在后台运行推理,暂时还不支持依赖的接口
// Background json.RawMessage `json:"background,omitempty"`
Conversation
json
.
RawMessage
`json:"conversation,omitempty"`
ContextManagement
json
.
RawMessage
`json:"context_management,omitempty"`
Instructions
json
.
RawMessage
`json:"instructions,omitempty"`
Instructions
json
.
RawMessage
`json:"instructions,omitempty"`
MaxOutputTokens
uint
`json:"max_output_tokens,omitempty"`
MaxOutputTokens
uint
`json:"max_output_tokens,omitempty"`
TopLogProbs
*
int
`json:"top_logprobs,omitempty"`
Metadata
json
.
RawMessage
`json:"metadata,omitempty"`
Metadata
json
.
RawMessage
`json:"metadata,omitempty"`
ParallelToolCalls
json
.
RawMessage
`json:"parallel_tool_calls,omitempty"`
ParallelToolCalls
json
.
RawMessage
`json:"parallel_tool_calls,omitempty"`
PreviousResponseID
string
`json:"previous_response_id,omitempty"`
PreviousResponseID
string
`json:"previous_response_id,omitempty"`
...
@@ -813,7 +822,9 @@ type OpenAIResponsesRequest struct {
...
@@ -813,7 +822,9 @@ type OpenAIResponsesRequest struct {
Store
json
.
RawMessage
`json:"store,omitempty"`
Store
json
.
RawMessage
`json:"store,omitempty"`
PromptCacheKey
json
.
RawMessage
`json:"prompt_cache_key,omitempty"`
PromptCacheKey
json
.
RawMessage
`json:"prompt_cache_key,omitempty"`
PromptCacheRetention
json
.
RawMessage
`json:"prompt_cache_retention,omitempty"`
PromptCacheRetention
json
.
RawMessage
`json:"prompt_cache_retention,omitempty"`
SafetyIdentifier
string
`json:"safety_identifier,omitempty"`
Stream
bool
`json:"stream,omitempty"`
Stream
bool
`json:"stream,omitempty"`
StreamOptions
*
StreamOptions
`json:"stream_options,omitempty"`
Temperature
*
float64
`json:"temperature,omitempty"`
Temperature
*
float64
`json:"temperature,omitempty"`
Text
json
.
RawMessage
`json:"text,omitempty"`
Text
json
.
RawMessage
`json:"text,omitempty"`
ToolChoice
json
.
RawMessage
`json:"tool_choice,omitempty"`
ToolChoice
json
.
RawMessage
`json:"tool_choice,omitempty"`
...
...
relay/common/relay_info.go
View file @
4746b2bf
...
@@ -702,6 +702,7 @@ func FailTaskInfo(reason string) *TaskInfo {
...
@@ -702,6 +702,7 @@ func FailTaskInfo(reason string) *TaskInfo {
// service_tier: 服务层级字段,可能导致额外计费(OpenAI、Claude、Responses API 支持)
// service_tier: 服务层级字段,可能导致额外计费(OpenAI、Claude、Responses API 支持)
// store: 数据存储授权字段,涉及用户隐私(仅 OpenAI、Responses API 支持,默认允许透传,禁用后可能导致 Codex 无法使用)
// store: 数据存储授权字段,涉及用户隐私(仅 OpenAI、Responses API 支持,默认允许透传,禁用后可能导致 Codex 无法使用)
// safety_identifier: 安全标识符,用于向 OpenAI 报告违规用户(仅 OpenAI 支持,涉及用户隐私)
// safety_identifier: 安全标识符,用于向 OpenAI 报告违规用户(仅 OpenAI 支持,涉及用户隐私)
// stream_options.include_obfuscation: 响应流混淆控制字段(仅 OpenAI Responses API 支持)
func
RemoveDisabledFields
(
jsonData
[]
byte
,
channelOtherSettings
dto
.
ChannelOtherSettings
)
([]
byte
,
error
)
{
func
RemoveDisabledFields
(
jsonData
[]
byte
,
channelOtherSettings
dto
.
ChannelOtherSettings
)
([]
byte
,
error
)
{
var
data
map
[
string
]
interface
{}
var
data
map
[
string
]
interface
{}
if
err
:=
common
.
Unmarshal
(
jsonData
,
&
data
);
err
!=
nil
{
if
err
:=
common
.
Unmarshal
(
jsonData
,
&
data
);
err
!=
nil
{
...
@@ -730,6 +731,22 @@ func RemoveDisabledFields(jsonData []byte, channelOtherSettings dto.ChannelOther
...
@@ -730,6 +731,22 @@ func RemoveDisabledFields(jsonData []byte, channelOtherSettings dto.ChannelOther
}
}
}
}
// 默认移除 stream_options.include_obfuscation,除非明确允许(避免关闭响应流混淆保护)
if
!
channelOtherSettings
.
AllowIncludeObfuscation
{
if
streamOptionsAny
,
exists
:=
data
[
"stream_options"
];
exists
{
if
streamOptions
,
ok
:=
streamOptionsAny
.
(
map
[
string
]
interface
{});
ok
{
if
_
,
includeExists
:=
streamOptions
[
"include_obfuscation"
];
includeExists
{
delete
(
streamOptions
,
"include_obfuscation"
)
}
if
len
(
streamOptions
)
==
0
{
delete
(
data
,
"stream_options"
)
}
else
{
data
[
"stream_options"
]
=
streamOptions
}
}
}
}
jsonDataAfter
,
err
:=
common
.
Marshal
(
data
)
jsonDataAfter
,
err
:=
common
.
Marshal
(
data
)
if
err
!=
nil
{
if
err
!=
nil
{
common
.
SysError
(
"RemoveDisabledFields Marshal error :"
+
err
.
Error
())
common
.
SysError
(
"RemoveDisabledFields Marshal error :"
+
err
.
Error
())
...
...
web/src/components/table/channels/modals/EditChannelModal.jsx
View file @
4746b2bf
...
@@ -170,6 +170,7 @@ const EditChannelModal = (props) => {
...
@@ -170,6 +170,7 @@ const EditChannelModal = (props) => {
allow_service_tier
:
false
,
allow_service_tier
:
false
,
disable_store
:
false
,
// false = 允许透传(默认开启)
disable_store
:
false
,
// false = 允许透传(默认开启)
allow_safety_identifier
:
false
,
allow_safety_identifier
:
false
,
allow_include_obfuscation
:
false
,
claude_beta_query
:
false
,
claude_beta_query
:
false
,
};
};
const
[
batch
,
setBatch
]
=
useState
(
false
);
const
[
batch
,
setBatch
]
=
useState
(
false
);
...
@@ -634,6 +635,8 @@ const EditChannelModal = (props) => {
...
@@ -634,6 +635,8 @@ const EditChannelModal = (props) => {
data
.
disable_store
=
parsedSettings
.
disable_store
||
false
;
data
.
disable_store
=
parsedSettings
.
disable_store
||
false
;
data
.
allow_safety_identifier
=
data
.
allow_safety_identifier
=
parsedSettings
.
allow_safety_identifier
||
false
;
parsedSettings
.
allow_safety_identifier
||
false
;
data
.
allow_include_obfuscation
=
parsedSettings
.
allow_include_obfuscation
||
false
;
data
.
claude_beta_query
=
parsedSettings
.
claude_beta_query
||
false
;
data
.
claude_beta_query
=
parsedSettings
.
claude_beta_query
||
false
;
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'解析其他设置失败:'
,
error
);
console
.
error
(
'解析其他设置失败:'
,
error
);
...
@@ -645,6 +648,7 @@ const EditChannelModal = (props) => {
...
@@ -645,6 +648,7 @@ const EditChannelModal = (props) => {
data
.
allow_service_tier
=
false
;
data
.
allow_service_tier
=
false
;
data
.
disable_store
=
false
;
data
.
disable_store
=
false
;
data
.
allow_safety_identifier
=
false
;
data
.
allow_safety_identifier
=
false
;
data
.
allow_include_obfuscation
=
false
;
data
.
claude_beta_query
=
false
;
data
.
claude_beta_query
=
false
;
}
}
}
else
{
}
else
{
...
@@ -655,6 +659,7 @@ const EditChannelModal = (props) => {
...
@@ -655,6 +659,7 @@ const EditChannelModal = (props) => {
data
.
allow_service_tier
=
false
;
data
.
allow_service_tier
=
false
;
data
.
disable_store
=
false
;
data
.
disable_store
=
false
;
data
.
allow_safety_identifier
=
false
;
data
.
allow_safety_identifier
=
false
;
data
.
allow_include_obfuscation
=
false
;
data
.
claude_beta_query
=
false
;
data
.
claude_beta_query
=
false
;
}
}
...
@@ -1392,11 +1397,13 @@ const EditChannelModal = (props) => {
...
@@ -1392,11 +1397,13 @@ const EditChannelModal = (props) => {
// type === 1 (OpenAI) 或 type === 14 (Claude): 设置字段透传控制(显式保存布尔值)
// type === 1 (OpenAI) 或 type === 14 (Claude): 设置字段透传控制(显式保存布尔值)
if
(
localInputs
.
type
===
1
||
localInputs
.
type
===
14
)
{
if
(
localInputs
.
type
===
1
||
localInputs
.
type
===
14
)
{
settings
.
allow_service_tier
=
localInputs
.
allow_service_tier
===
true
;
settings
.
allow_service_tier
=
localInputs
.
allow_service_tier
===
true
;
// 仅 OpenAI 渠道需要 store
和 safety_identifier
// 仅 OpenAI 渠道需要 store
/ safety_identifier / include_obfuscation
if
(
localInputs
.
type
===
1
)
{
if
(
localInputs
.
type
===
1
)
{
settings
.
disable_store
=
localInputs
.
disable_store
===
true
;
settings
.
disable_store
=
localInputs
.
disable_store
===
true
;
settings
.
allow_safety_identifier
=
settings
.
allow_safety_identifier
=
localInputs
.
allow_safety_identifier
===
true
;
localInputs
.
allow_safety_identifier
===
true
;
settings
.
allow_include_obfuscation
=
localInputs
.
allow_include_obfuscation
===
true
;
}
}
if
(
localInputs
.
type
===
14
)
{
if
(
localInputs
.
type
===
14
)
{
settings
.
claude_beta_query
=
localInputs
.
claude_beta_query
===
true
;
settings
.
claude_beta_query
=
localInputs
.
claude_beta_query
===
true
;
...
@@ -1421,6 +1428,7 @@ const EditChannelModal = (props) => {
...
@@ -1421,6 +1428,7 @@ const EditChannelModal = (props) => {
delete
localInputs
.
allow_service_tier
;
delete
localInputs
.
allow_service_tier
;
delete
localInputs
.
disable_store
;
delete
localInputs
.
disable_store
;
delete
localInputs
.
allow_safety_identifier
;
delete
localInputs
.
allow_safety_identifier
;
delete
localInputs
.
allow_include_obfuscation
;
delete
localInputs
.
claude_beta_query
;
delete
localInputs
.
claude_beta_query
;
let
res
;
let
res
;
...
@@ -3271,6 +3279,24 @@ const EditChannelModal = (props) => {
...
@@ -3271,6 +3279,24 @@ const EditChannelModal = (props) => {
'safety_identifier 字段用于帮助 OpenAI 识别可能违反使用政策的应用程序用户。默认关闭以保护用户隐私'
,
'safety_identifier 字段用于帮助 OpenAI 识别可能违反使用政策的应用程序用户。默认关闭以保护用户隐私'
,
)
}
)
}
/>
/>
<
Form
.
Switch
field=
'allow_include_obfuscation'
label=
{
t
(
'允许 stream_options.include_obfuscation 透传'
,
)
}
checkedText=
{
t
(
'开'
)
}
uncheckedText=
{
t
(
'关'
)
}
onChange=
{
(
value
)
=>
handleChannelOtherSettingsChange
(
'allow_include_obfuscation'
,
value
,
)
}
extraText=
{
t
(
'include_obfuscation 用于控制 Responses 流混淆字段。默认关闭以避免客户端关闭该安全保护'
,
)
}
/>
</>
</>
)
}
)
}
...
...
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