From 39641e7e68f8923d7106119de0894d520dea7b5f Mon Sep 17 00:00:00 2001 From: YutaSaito <36355491+uc4w6c@users.noreply.github.com> Date: Wed, 22 Oct 2025 07:18:55 +0900 Subject: [PATCH] chore: rename GraySwan to Gray Swan (#15771) --- .../docs/proxy/guardrails/grayswan.md | 14 +++---- .../guardrail_hooks/grayswan/__init__.py | 4 +- .../guardrail_hooks/grayswan/grayswan.py | 38 +++++++++---------- .../guardrails/guardrail_hooks/grayswan.py | 20 +++++----- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/docs/my-website/docs/proxy/guardrails/grayswan.md b/docs/my-website/docs/proxy/guardrails/grayswan.md index 325df169150..dbd9258292b 100644 --- a/docs/my-website/docs/proxy/guardrails/grayswan.md +++ b/docs/my-website/docs/proxy/guardrails/grayswan.md @@ -1,9 +1,9 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# GraySwan Cygnal Guardrail +# Gray Swan Cygnal Guardrail -Use [GraySwan Cygnal](https://docs.grayswan.ai/cygnal/monitor-requests) to continuously monitor conversations for policy violations, indirect prompt injection (IPI), jailbreak attempts, and other safety risks. +Use [Gray Swan Cygnal](https://docs.grayswan.ai/cygnal/monitor-requests) to continuously monitor conversations for policy violations, indirect prompt injection (IPI), jailbreak attempts, and other safety risks. Cygnal returns a `violation` score between `0` and `1` (higher means more likely to violate policy), plus metadata such as violated rule indices, mutation detection, and IPI flags. LiteLLM can automatically block or monitor requests based on this signal. @@ -13,7 +13,7 @@ Cygnal returns a `violation` score between `0` and `1` (higher means more likely ### 1. Obtain Credentials -1. Create a GraySwan account and generate a Cygnal API key. +1. Create a Gray Swan account and generate a Cygnal API key. 2. Configure environment variables for the LiteLLM proxy host: ```bash @@ -22,7 +22,7 @@ export GRAYSWAN_API_KEY="your-grayswan-key" ### 2. Configure `config.yaml` -Add a guardrail entry that references the GraySwan integration. Below is a balanced example that monitors both input and output but only blocks once the violation score reaches the configured threshold. +Add a guardrail entry that references the Gray Swan integration. Below is a balanced example that monitors both input and output but only blocks once the violation score reaches the configured threshold. ```yaml model_list: @@ -63,7 +63,7 @@ litellm --config config.yaml --port 4000 ## Choosing Guardrail Modes -GraySwan can run during `pre_call`, `during_call`, and `post_call` stages. Combine modes based on your latency and coverage requirements. +Gray Swan can run during `pre_call`, `during_call`, and `post_call` stages. Combine modes based on your latency and coverage requirements. | Mode | When it Runs | Protects | Typical Use Case | |--------------|-------------------|-----------------------|------------------| @@ -138,10 +138,10 @@ Provides the strongest enforcement by inspecting both prompts and responses. | Parameter | Type | Description | |---------------------------------------|-----------------|-------------| -| `api_key` | string | GraySwan Cygnal API key. Reads from `GRAYSWAN_API_KEY` if omitted. | +| `api_key` | string | Gray Swan Cygnal API key. Reads from `GRAYSWAN_API_KEY` if omitted. | | `mode` | string or list | Guardrail stages (`pre_call`, `during_call`, `post_call`). | | `optional_params.on_flagged_action` | string | `monitor` (log only) or `block` (raise `HTTPException`). | | `.optional_params.violation_threshold`| number (0-1) | Scores at or above this value are considered violations. | | `optional_params.reasoning_mode` | string | `off`, `hybrid`, or `thinking`. Enables Cygnal’s reasoning capabilities. | | `optional_params.categories` | object | Map of custom category names to descriptions. | -| `optional_params.policy_id` | string | GraySwan policy identifier. | +| `optional_params.policy_id` | string | Gray Swan policy identifier. | diff --git a/litellm/proxy/guardrails/guardrail_hooks/grayswan/__init__.py b/litellm/proxy/guardrails/guardrail_hooks/grayswan/__init__.py index ffb38b1ac34..389340014f8 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/grayswan/__init__.py +++ b/litellm/proxy/guardrails/guardrail_hooks/grayswan/__init__.py @@ -1,4 +1,4 @@ -"""GraySwan Cygnal guardrail integration for LiteLLM.""" +"""Gray Swan Cygnal guardrail integration for LiteLLM.""" from typing import TYPE_CHECKING @@ -21,7 +21,7 @@ def initialize_guardrail( guardrail_name = guardrail.get("guardrail_name") if not guardrail_name: - raise ValueError("GraySwan guardrail requires a guardrail_name") + raise ValueError("Gray Swan guardrail requires a guardrail_name") optional_params = getattr(litellm_params, "optional_params", None) diff --git a/litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py b/litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py index 247b144a142..00e30d3e5ba 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py +++ b/litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py @@ -1,4 +1,4 @@ -"""GraySwan Cygnal guardrail integration.""" +"""Gray Swan Cygnal guardrail integration.""" import os from typing import Any, Dict, Literal, Optional, Union @@ -24,16 +24,16 @@ from litellm.types.utils import LLMResponseTypes class GraySwanGuardrailMissingSecrets(Exception): - """Raised when the GraySwan API key is missing.""" + """Raised when the Gray Swan API key is missing.""" class GraySwanGuardrailAPIError(Exception): - """Raised when the GraySwan API returns an error.""" + """Raised when the Gray Swan API returns an error.""" class GraySwanGuardrail(CustomGuardrail): """ - Guardrail that calls GraySwan's Cygnal monitoring endpoint. + Guardrail that calls Gray Swan's Cygnal monitoring endpoint. see: https://docs.grayswan.ai/cygnal/monitor-requests """ @@ -63,7 +63,7 @@ class GraySwanGuardrail(CustomGuardrail): api_key_value = api_key or os.getenv("GRAYSWAN_API_KEY") if not api_key_value: raise GraySwanGuardrailMissingSecrets( - "GraySwan API key missing. Set `GRAYSWAN_API_KEY` or pass `api_key`." + "Gray Swan API key missing. Set `GRAYSWAN_API_KEY` or pass `api_key`." ) self.api_key: str = api_key_value @@ -77,7 +77,7 @@ class GraySwanGuardrail(CustomGuardrail): else: if action: verbose_proxy_logger.warning( - "GraySwan Guardrail: Unsupported on_flagged_action '%s', defaulting to '%s'.", + "Gray Swan Guardrail: Unsupported on_flagged_action '%s', defaulting to '%s'.", action, self.DEFAULT_ON_FLAGGED_ACTION, ) @@ -131,11 +131,11 @@ class GraySwanGuardrail(CustomGuardrail): ): return data - verbose_proxy_logger.debug("GraySwan Guardrail: pre-call hook triggered") + verbose_proxy_logger.debug("Gray Swan Guardrail: pre-call hook triggered") messages = data.get("messages") if not messages: - verbose_proxy_logger.debug("GraySwan Guardrail: No messages in data") + verbose_proxy_logger.debug("Gray Swan Guardrail: No messages in data") return data dynamic_body = self.get_guardrail_dynamic_request_body_params(data) or {} @@ -143,7 +143,7 @@ class GraySwanGuardrail(CustomGuardrail): payload = self._prepare_payload(messages, dynamic_body) if payload is None: verbose_proxy_logger.debug( - "GraySwan Guardrail: no content to scan; skipping request" + "Gray Swan Guardrail: no content to scan; skipping request" ) return data @@ -181,7 +181,7 @@ class GraySwanGuardrail(CustomGuardrail): messages = data.get("messages") if not messages: - verbose_proxy_logger.debug("GraySwan Guardrail: No messages in data") + verbose_proxy_logger.debug("Gray Swan Guardrail: No messages in data") return data dynamic_body = self.get_guardrail_dynamic_request_body_params(data) or {} @@ -189,7 +189,7 @@ class GraySwanGuardrail(CustomGuardrail): payload = self._prepare_payload(messages, dynamic_body) if payload is None: verbose_proxy_logger.debug( - "GraySwan Guardrail: no content to scan; skipping request" + "Gray Swan Guardrail: no content to scan; skipping request" ) return data @@ -227,7 +227,7 @@ class GraySwanGuardrail(CustomGuardrail): if not response_messages: verbose_proxy_logger.debug( - "GraySwan Guardrail: no response messages detected; skipping post-call scan" + "Gray Swan Guardrail: no response messages detected; skipping post-call scan" ) return response @@ -236,7 +236,7 @@ class GraySwanGuardrail(CustomGuardrail): payload = self._prepare_payload(response_messages, dynamic_body) if payload is None: verbose_proxy_logger.debug( - "GraySwan Guardrail: no content to scan; skipping request" + "Gray Swan Guardrail: no content to scan; skipping request" ) return response @@ -263,13 +263,13 @@ class GraySwanGuardrail(CustomGuardrail): response.raise_for_status() result = response.json() verbose_proxy_logger.debug( - "GraySwan Guardrail: monitor response %s", safe_dumps(result) + "Gray Swan Guardrail: monitor response %s", safe_dumps(result) ) except HTTPException: raise except Exception as exc: # pragma: no cover - depends on HTTP client behaviour verbose_proxy_logger.exception( - "GraySwan Guardrail: API request failed: %s", exc + "Gray Swan Guardrail: API request failed: %s", exc ) raise GraySwanGuardrailAPIError(str(exc)) from exc @@ -315,14 +315,14 @@ class GraySwanGuardrail(CustomGuardrail): flagged = violation_score >= self.violation_threshold if not flagged: verbose_proxy_logger.debug( - "GraySwan Guardrail: request passed (score=%s, rules=%s)", + "Gray Swan Guardrail: request passed (score=%s, rules=%s)", violation_score, violated_rules, ) return verbose_proxy_logger.warning( - "GraySwan Guardrail: violation score %.3f exceeds threshold %.3f", + "Gray Swan Guardrail: violation score %.3f exceeds threshold %.3f", violation_score, self.violation_threshold, ) @@ -331,7 +331,7 @@ class GraySwanGuardrail(CustomGuardrail): raise HTTPException( status_code=400, detail={ - "error": "Blocked by GraySwan Guardrail", + "error": "Blocked by Gray Swan Guardrail", "violation": violation_score, "violated_rules": violated_rules, "mutation": mutation_detected, @@ -351,7 +351,7 @@ class GraySwanGuardrail(CustomGuardrail): if normalised in self.SUPPORTED_REASONING_MODES: return normalised verbose_proxy_logger.warning( - "GraySwan Guardrail: ignoring unsupported reasoning_mode '%s'", + "Gray Swan Guardrail: ignoring unsupported reasoning_mode '%s'", candidate, ) return None diff --git a/litellm/types/proxy/guardrails/guardrail_hooks/grayswan.py b/litellm/types/proxy/guardrails/guardrail_hooks/grayswan.py index 93836f23086..d50ae95ee39 100644 --- a/litellm/types/proxy/guardrails/guardrail_hooks/grayswan.py +++ b/litellm/types/proxy/guardrails/guardrail_hooks/grayswan.py @@ -1,4 +1,4 @@ -"""GraySwan guardrail configuration models.""" +"""Gray Swan guardrail configuration models.""" from typing import Dict, Optional @@ -8,7 +8,7 @@ from .base import GuardrailConfigModel class GraySwanGuardrailConfigModelOptionalParams(BaseModel): - """Optional parameters for the GraySwan guardrail.""" + """Optional parameters for the Gray Swan guardrail.""" on_flagged_action: Optional[str] = Field( default="monitor", @@ -18,36 +18,36 @@ class GraySwanGuardrailConfigModelOptionalParams(BaseModel): default=0.5, ge=0.0, le=1.0, - description="Threshold between 0 and 1 at which GraySwan violations trigger the configured action.", + description="Threshold between 0 and 1 at which Gray Swan violations trigger the configured action.", ) reasoning_mode: Optional[str] = Field( default=None, - description="GraySwan reasoning mode override. Accepted values: 'off', 'hybrid', 'thinking'.", + description="Gray Swan reasoning mode override. Accepted values: 'off', 'hybrid', 'thinking'.", ) policy_id: Optional[str] = Field( default=None, - description="GraySwan policy identifier to apply during monitoring.", + description="Gray Swan policy identifier to apply during monitoring.", ) categories: Optional[Dict[str, str]] = Field( default=None, - description="Default GraySwan category definitions to send with each request.", + description="Default Gray Swan category definitions to send with each request.", ) class GraySwanGuardrailConfigModel( GuardrailConfigModel[GraySwanGuardrailConfigModelOptionalParams] ): - """Configuration parameters for the GraySwan guardrail.""" + """Configuration parameters for the Gray Swan guardrail.""" api_key: Optional[str] = Field( default=None, - description="API key for GraySwan. Reads from the `GRAYSWAN_API_KEY` environment variable when omitted.", + description="API key for Gray Swan. Reads from the `GRAYSWAN_API_KEY` environment variable when omitted.", ) api_base: Optional[str] = Field( default=None, - description="Override for the GraySwan API base URL. Defaults to https://api.grayswan.ai and can be set via `GRAYSWAN_API_BASE`.", + description="Override for the Gray Swan API base URL. Defaults to https://api.grayswan.ai and can be set via `GRAYSWAN_API_BASE`.", ) @staticmethod def ui_friendly_name() -> str: - return "GraySwan Guardrail" + return "Gray Swan Guardrail"