fix(openai): implement rollback mechanism for missing instructions in passthrough mode#2498
Closed
Simba98 wants to merge 7 commits into
Closed
fix(openai): implement rollback mechanism for missing instructions in passthrough mode#2498Simba98 wants to merge 7 commits into
Simba98 wants to merge 7 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR changes OAuth passthrough behavior so that when the request is missing instructions, the service rolls back to the non-passthrough (legacy/full transform) path instead of locally returning a 403, and updates/extends tests accordingly.
Changes:
- Add a typed rollback error to signal “missing instructions” detection in the passthrough path.
- Update
Forwardto catch the rollback error and continue via the non-passthrough transform path. - Adjust and add tests to validate the rollback behavior and update request bodies to include
instructionswhere needed.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| backend/internal/service/openai_gateway_service.go | Introduces rollback error + rollback handling in Forward, and changes instructions detection behavior in OAuth passthrough. |
| backend/internal/service/openai_oauth_passthrough_test.go | Updates existing tests and adds coverage for passthrough rollback to legacy transform when instructions is missing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if !strings.Contains(model, "codex") { | ||
| return "" | ||
| } | ||
| _ = reqModel |
Comment on lines
5852
to
+5853
| func detectOpenAIPassthroughInstructionsRejectReason(reqModel string, body []byte) string { | ||
| model := strings.ToLower(strings.TrimSpace(reqModel)) | ||
| if !strings.Contains(model, "codex") { | ||
| return "" | ||
| } | ||
| _ = reqModel |
Comment on lines
2877
to
2881
| if account != nil && account.Type == AccountTypeOAuth { | ||
| if rejectReason := detectOpenAIPassthroughInstructionsRejectReason(reqModel, body); rejectReason != "" { | ||
| rejectMsg := "OpenAI codex passthrough requires a non-empty instructions field" | ||
| setOpsUpstreamError(c, http.StatusForbidden, rejectMsg, "") | ||
| appendOpsUpstreamError(c, OpsUpstreamErrorEvent{ | ||
| Platform: account.Platform, | ||
| AccountID: account.ID, | ||
| AccountName: account.Name, | ||
| UpstreamStatusCode: http.StatusForbidden, | ||
| Passthrough: true, | ||
| Kind: "request_error", | ||
| Message: rejectMsg, | ||
| Detail: rejectReason, | ||
| }) | ||
| logOpenAIPassthroughInstructionsRejected(ctx, c, account, reqModel, rejectReason, body) | ||
| c.JSON(http.StatusForbidden, gin.H{ | ||
| "error": gin.H{ | ||
| "type": "forbidden_error", | ||
| "message": rejectMsg, | ||
| }, | ||
| }) | ||
| return nil, fmt.Errorf("openai passthrough rejected before upstream: %s", rejectReason) | ||
| return nil, &openAIPassthroughRollbackError{Reason: rejectReason} | ||
| } |
| } | ||
|
|
||
| func TestOpenAIGatewayService_OAuthPassthrough_CodexMissingInstructionsRejectedBeforeUpstream(t *testing.T) { | ||
| func TestOpenAIGatewayService_OAuthPassthrough_MissingInstructionsRejectedBeforeUpstream(t *testing.T) { |
Comment on lines
+494
to
+497
| _, err := svc.Forward(context.Background(), c, account, originalBody) | ||
| require.NoError(t, err) | ||
| // 回退后上游应收到请求(非透传路径已处理)。 | ||
| require.NotNil(t, upstream.lastReq) |
Comment on lines
+498
to
+499
| // 不应写入 403 响应。 | ||
| require.NotEqual(t, http.StatusForbidden, rec.Code) |
7464580 to
d708c15
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 摘要
中文
本 PR 修复 OpenAI OAuth 透传路径在请求缺少
instructions字段时的处理逻辑。此前透传路径会在本地直接返回 403,导致请求无法继续通过非透传路径进行完整转换。现在当检测到缺失
instructions时,透传路径会记录告警并回退到非透传路径,由完整转换逻辑重新打包请求体后继续转发到上游。同时,
instructions缺失检测不再仅限于 Codex 模型,而是适用于 OAuth 可用模型的透传场景,以匹配上游对instructions字段的实际要求。现在已经测试gpt-5.5 gpt-5.4 gpt-5.4-mini gpt-5.2 现在都要求instructions ( 上游返回 Instructions are required ), 而不是仅有codex要求instructions。English
This PR fixes OpenAI OAuth passthrough behavior when the request body is missing the
instructionsfield.Previously, the passthrough path rejected such requests locally with a 403 response, preventing the request from continuing through the non-passthrough full transform path. With this change, missing
instructionsnow triggers a passthrough rollback: the gateway logs the warning, falls back to the non-passthrough path, repacks the request body, and forwards it upstream.The missing
instructionsdetection is also expanded beyond Codex-only models to OAuth-supported passthrough requests, aligning local gateway behavior with upstream requirements. Now gpt-5.5 gpt-5.4 gpt-5.4-mini gpt-5.2 all need instructions, upstream returns Instructions are required for all models not only codex models.Changes / 变更内容
中文
openAIPassthroughRollbackError,用于在透传路径尚未写入响应时通知上层回退。Forward中捕获透传回退错误,并继续执行非透传完整转换路径。instructions的处理从本地 403 拒绝改为记录告警后回退。instructions缺失检测范围,不再只判断 Codex 模型。instructions的场景。English
openAIPassthroughRollbackErrorto signal rollback before any response is written.Forwardto catch passthrough rollback errors and continue through the non-passthrough full transform path.instructionshandling from local 403 rejection to warning + rollback.instructionsdetection beyond Codex-only model checks.instructionsin normal passthrough test cases.Changed Files / 影响文件
Commits / 相关提交
c63f429407cd78a90ecbf502cdae8dc3736f2abefix(openai): implement rollback mechanism for missing instructions in passthrougha038fffec3ba0efb1bdebcf2780e4741953e02eefix(openai): reflect changes in instruction handling for OAuth upstreamTesting / 测试
中文
已运行 OpenAI passthrough 相关 Go 测试: