mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-23 10:19:45 +00:00
fix(openai): 非 OAuth 账号 Chat Completions 也提取 system 消息并注入 instructions
GPT-5/Codex 等模型要求请求中必须包含 instructions 字段。 之前 extractSystemMessagesFromInput + applyInstructions 仅在 OAuth 路径执行,API Key 账号走 Chat Completions 时 system 消息 保留在 input 中但缺少 instructions,导致上游返回 400。 同时在 ChatCompletionsRequest 和 ResponsesRequest 中增加 Instructions 字段,支持客户端直接传入 instructions 透传到上游。
This commit is contained in:
@@ -27,8 +27,9 @@ func ChatCompletionsToResponses(req *ChatCompletionsRequest) (*ResponsesRequest,
|
||||
}
|
||||
|
||||
out := &ResponsesRequest{
|
||||
Model: req.Model,
|
||||
Input: inputJSON,
|
||||
Model: req.Model,
|
||||
Instructions: req.Instructions,
|
||||
Input: inputJSON,
|
||||
Temperature: req.Temperature,
|
||||
TopP: req.TopP,
|
||||
Stream: true, // upstream always streams
|
||||
|
||||
@@ -152,6 +152,7 @@ type AnthropicDelta struct {
|
||||
// ResponsesRequest is the request body for POST /v1/responses.
|
||||
type ResponsesRequest struct {
|
||||
Model string `json:"model"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
Input json.RawMessage `json:"input"` // string or []ResponsesInputItem
|
||||
MaxOutputTokens *int `json:"max_output_tokens,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
@@ -337,6 +338,7 @@ type ResponsesStreamEvent struct {
|
||||
type ChatCompletionsRequest struct {
|
||||
Model string `json:"model"`
|
||||
Messages []ChatMessage `json:"messages"`
|
||||
Instructions string `json:"instructions,omitempty"` // OpenAI Responses API compat
|
||||
MaxTokens *int `json:"max_tokens,omitempty"`
|
||||
MaxCompletionTokens *int `json:"max_completion_tokens,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
|
||||
@@ -82,20 +82,35 @@ func (s *OpenAIGatewayService) ForwardAsChatCompletions(
|
||||
return nil, fmt.Errorf("marshal responses request: %w", err)
|
||||
}
|
||||
|
||||
if account.Type == AccountTypeOAuth {
|
||||
{
|
||||
var reqBody map[string]any
|
||||
if err := json.Unmarshal(responsesBody, &reqBody); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal for codex transform: %w", err)
|
||||
}
|
||||
codexResult := applyCodexOAuthTransform(reqBody, false, false)
|
||||
if codexResult.PromptCacheKey != "" {
|
||||
promptCacheKey = codexResult.PromptCacheKey
|
||||
} else if promptCacheKey != "" {
|
||||
reqBody["prompt_cache_key"] = promptCacheKey
|
||||
modified := false
|
||||
if account.Type == AccountTypeOAuth {
|
||||
codexResult := applyCodexOAuthTransform(reqBody, false, false)
|
||||
modified = codexResult.Modified
|
||||
if codexResult.PromptCacheKey != "" {
|
||||
promptCacheKey = codexResult.PromptCacheKey
|
||||
} else if promptCacheKey != "" {
|
||||
reqBody["prompt_cache_key"] = promptCacheKey
|
||||
}
|
||||
} else {
|
||||
// 非 OAuth 账号也需要提取 system 消息并注入 instructions,
|
||||
// 否则上游 GPT-5/Codex 等模型会报 "Instructions are required"。
|
||||
if extractSystemMessagesFromInput(reqBody) {
|
||||
modified = true
|
||||
}
|
||||
if applyInstructions(reqBody, false) {
|
||||
modified = true
|
||||
}
|
||||
}
|
||||
responsesBody, err = json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("remarshal after codex transform: %w", err)
|
||||
if modified {
|
||||
responsesBody, err = json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("remarshal after codex transform: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user