From 9c56fe0b0bd72c7d3630830deda1412e341fe6b2 Mon Sep 17 00:00:00 2001 From: benjamin Date: Tue, 26 May 2026 17:21:45 +0800 Subject: [PATCH] fix(openai): mark fast-policy entrypoints business-limited Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- backend/internal/service/openai_gateway_chat_completions.go | 1 + backend/internal/service/openai_gateway_chat_completions_raw.go | 1 + backend/internal/service/openai_gateway_messages.go | 1 + backend/internal/service/openai_ws_forwarder.go | 1 + backend/internal/service/openai_ws_v2_passthrough_adapter.go | 2 ++ 5 files changed, 6 insertions(+) diff --git a/backend/internal/service/openai_gateway_chat_completions.go b/backend/internal/service/openai_gateway_chat_completions.go index 27eb211e..f49b3218 100644 --- a/backend/internal/service/openai_gateway_chat_completions.go +++ b/backend/internal/service/openai_gateway_chat_completions.go @@ -193,6 +193,7 @@ func (s *OpenAIGatewayService) ForwardAsChatCompletions( if policyErr != nil { var blocked *OpenAIFastBlockedError if errors.As(policyErr, &blocked) { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) writeChatCompletionsError(c, http.StatusForbidden, "permission_error", blocked.Message) } return nil, policyErr diff --git a/backend/internal/service/openai_gateway_chat_completions_raw.go b/backend/internal/service/openai_gateway_chat_completions_raw.go index 19f99f69..efac4671 100644 --- a/backend/internal/service/openai_gateway_chat_completions_raw.go +++ b/backend/internal/service/openai_gateway_chat_completions_raw.go @@ -93,6 +93,7 @@ func (s *OpenAIGatewayService) forwardAsRawChatCompletions( if policyErr != nil { var blocked *OpenAIFastBlockedError if errors.As(policyErr, &blocked) { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) writeChatCompletionsError(c, http.StatusForbidden, "permission_error", blocked.Message) } return nil, policyErr diff --git a/backend/internal/service/openai_gateway_messages.go b/backend/internal/service/openai_gateway_messages.go index 336a7d79..662d2a69 100644 --- a/backend/internal/service/openai_gateway_messages.go +++ b/backend/internal/service/openai_gateway_messages.go @@ -231,6 +231,7 @@ func (s *OpenAIGatewayService) ForwardAsAnthropic( if policyErr != nil { var blocked *OpenAIFastBlockedError if errors.As(policyErr, &blocked) { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) writeAnthropicError(c, http.StatusForbidden, "forbidden_error", blocked.Message) } return nil, policyErr diff --git a/backend/internal/service/openai_ws_forwarder.go b/backend/internal/service/openai_ws_forwarder.go index 5edf4db9..d7452467 100644 --- a/backend/internal/service/openai_ws_forwarder.go +++ b/backend/internal/service/openai_ws_forwarder.go @@ -2612,6 +2612,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( return openAIWSClientPayload{}, NewOpenAIWSClientCloseError(coderws.StatusPolicyViolation, "invalid websocket request payload", policyErr) } if blocked != nil { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) // Send a Realtime-style error event to the client first, then // signal the handler to close the connection with PolicyViolation. // We intentionally do NOT forward this frame upstream. diff --git a/backend/internal/service/openai_ws_v2_passthrough_adapter.go b/backend/internal/service/openai_ws_v2_passthrough_adapter.go index 0a89e2dd..347a3b44 100644 --- a/backend/internal/service/openai_ws_v2_passthrough_adapter.go +++ b/backend/internal/service/openai_ws_v2_passthrough_adapter.go @@ -280,6 +280,7 @@ func (s *OpenAIGatewayService) proxyResponsesWebSocketV2Passthrough( return fmt.Errorf("apply openai fast policy on first ws frame: %w", policyErr) } if blocked != nil { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) // coder/websocket@v1.8.14 Conn.Write is synchronous: it acquires // writeFrameMu, writes the entire frame, and Flushes the underlying // bufio writer before returning (write.go:42 → write.go:307-311). @@ -442,6 +443,7 @@ func (s *OpenAIGatewayService) proxyResponsesWebSocketV2Passthrough( return out, blocked, policyErr }, onBlock: func(blocked *OpenAIFastBlockedError) { + MarkOpsClientBusinessLimited(c, OpsClientBusinessLimitedReasonLocalPolicyDenied) // See note above on Conn.Write being synchronous w.r.t. flush; // no explicit flush is required to ensure the error event lands // before the close frame.