Skip to content

Conversation

@steven10a
Copy link
Collaborator

@steven10a steven10a commented Oct 30, 2025

Fixes this reported BUG:

  • api_key passed in via client initialization is not properly passed to moderation check

The fix:

  • Default to using the guardrail_llm, if the moderation endpoint does not exist with that client, fall back to creating a compatible OpenAI client via env variable
  • Documentation already mentions how an OpenAI API key is required for the Moderation check
  • Added tests

Future PR to allow configuring an api_key specific to the moderation check via the config file (will only be needed for users who are using non-openai models as their base client).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the moderation guardrail's client selection logic to simplify how it chooses between the context client and fallback OpenAI client. The previous implementation attempted to detect if the context client pointed to the official OpenAI API by inspecting base URLs; the new approach attempts to use any context client first and falls back to the default OpenAI client if a NotFoundError is raised (indicating the moderation endpoint doesn't exist on third-party providers).

Key changes:

  • Simplified client selection logic using try-catch instead of URL inspection
  • Added NotFoundError exception handling for graceful fallback to OpenAI client
  • Added test coverage for both context client usage and third-party provider fallback scenarios

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/guardrails/checks/text/moderation.py Refactored moderation function to use try-catch pattern for client selection instead of URL-based detection; added NotFoundError import and exception handling for fallback logic
tests/unit/checks/test_moderation.py Added two new tests to verify context client usage and fallback behavior when moderation endpoint is unavailable
tests/conftest.py Added stub NotFoundError exception to support testing the new fallback logic

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@steven10a steven10a requested a review from Copilot October 30, 2025 20:01
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +176 to +192
# Try the context client first, fall back if moderation endpoint doesn't exist
if client is not None:
try:
candidate = getattr(context, "guardrail_llm", None)
if not isinstance(candidate, AsyncOpenAI):
return None

# Attempt to discover the effective base URL in a best-effort way
base_url = getattr(candidate, "base_url", None)
if base_url is None:
inner = getattr(candidate, "_client", None)
base_url = getattr(inner, "base_url", None) or getattr(inner, "_base_url", None)

# Reuse only when clearly the official OpenAI endpoint
if base_url is None:
return candidate
if isinstance(base_url, str) and "api.openai.com" in base_url:
return candidate
return None
except Exception:
return None

client = _maybe_reuse_openai_client_from_ctx(ctx) or _get_moderation_client()
resp = await client.moderations.create(
model="omni-moderation-latest",
input=data,
)
resp = await _call_moderation_api(client, data)
except NotFoundError as e:
# Moderation endpoint doesn't exist on this provider (e.g., third-party)
# Fall back to the OpenAI client
logger.debug(
"Moderation endpoint not available on context client, falling back to OpenAI: %s",
e,
)
client = _get_moderation_client()
resp = await _call_moderation_api(client, data)
else:
# No context client, use fallback
client = _get_moderation_client()
resp = await _call_moderation_api(client, data)
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code duplication: Lines 187-188 and 191-192 duplicate the same logic (getting fallback client and calling moderation API). Consider refactoring to avoid this duplication. For example, you could set client = _get_moderation_client() once and call resp = await _call_moderation_api(client, data) after the if-else block.

Copilot uses AI. Check for mistakes.
@gabor-openai gabor-openai changed the title Correctly pasing api key to moderation Correctly passing API key to moderation Oct 30, 2025
Copy link
Collaborator

@gabor-openai gabor-openai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TY!

@gabor-openai gabor-openai merged commit 1bfd82b into main Oct 30, 2025
9 checks passed
@gabor-openai gabor-openai deleted the dev/steven/moderation_bug branch October 30, 2025 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants