diff --git a/litellm/proxy/common_utils/callback_config_validation.py b/litellm/proxy/common_utils/callback_config_validation.py index 5931a8a8e01..c2be11ccc08 100644 --- a/litellm/proxy/common_utils/callback_config_validation.py +++ b/litellm/proxy/common_utils/callback_config_validation.py @@ -193,20 +193,30 @@ def cross_entry_family_error( ) +def _conflicting_option_error(var: str, incoming: str, stored_vars_by_entry: Sequence[Mapping[str, str]]) -> str | None: + return next( + ( + f"{var} is already set to {stored!r} by another callback entry. " + f"Every entry shares one value: remove that entry or send the same value." + for entry in stored_vars_by_entry + if (stored := entry.get(var)) not in (None, incoming) + ), + None, + ) + + def conflicting_shared_option_error( callback_vars: Mapping[str, str] | None, stored_vars_by_entry: Sequence[Mapping[str, str]], ) -> str | None: if not callback_vars: return None + incoming_by_var: Final = {var: callback_vars[var] for var in _SHARED_OPTION_VARS if var in callback_vars} return next( ( - f"{var} is already set to {stored!r} by another callback entry. " - f"Every entry shares one value: remove that entry or send the same value." - for var in _SHARED_OPTION_VARS - if (incoming := callback_vars.get(var)) is not None - for entry in stored_vars_by_entry - if (stored := entry.get(var)) not in (None, incoming) + error + for var, incoming in incoming_by_var.items() + if (error := _conflicting_option_error(var, incoming, stored_vars_by_entry)) is not None ), None, ) diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index df968e0bc9f..b5080536c71 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -17402,6 +17402,7 @@ export interface paths { * - langfuse_host: The host for the Langfuse callback * - langfuse_environment: The tracing environment for the Langfuse callback (lowercase; falls back to LANGFUSE_TRACING_ENVIRONMENT) * - langfuse_span_scope: For langfuse_otel, "full" (default) sends the whole request trace, "llm_only" sends only the model-call spans + * - capture_message_content: For the OTel v2 callbacks (langfuse_otel, arize, weave_otel, newrelic), "no_content" strips prompt and response content from this team's exported spans, "span_only" keeps whatever the global capture policy collects. Omitted behaves like "span_only". It only narrows: a team gets content only when the proxy's global OTel v2 capture is enabled * - gcs_bucket_name: The name of the GCS bucket * - gcs_path_service_account: The path to the GCS service account * - langsmith_api_key: The API key for the Langsmith callback