Adjusted based on comments

This commit is contained in:
yuneng-jiang 2025-11-07 15:02:41 -08:00
parent 0af3a51a97
commit 3a96c700b4
5 changed files with 82 additions and 38 deletions

View File

@ -81,6 +81,44 @@ class CustomLogger: # https://docs.litellm.ai/docs/observability/custom_callbac
self.turn_off_message_logging = turn_off_message_logging
pass
@staticmethod
def get_callback_env_vars(callback_name: Optional[str] = None) -> List[str]:
"""
Return the environment variables associated with a given callback
name as defined in the proxy callback registry.
Args:
callback_name: The name of the callback to look up.
Returns:
List[str]: A list of required environment variable names.
"""
if callback_name is None:
return []
normalized_name = callback_name.lower()
alias_map = {
"langfuse_otel": "langfuse",
}
lookup_name = alias_map.get(normalized_name, normalized_name)
try:
from litellm.proxy._types import AllCallbacks
except Exception:
return []
callbacks = AllCallbacks()
callback_info = getattr(callbacks, lookup_name, None)
if callback_info is None:
return []
params = getattr(callback_info, "litellm_callback_params", None)
if not params:
return []
return list(params)
def log_pre_api_call(self, model, messages, kwargs):
pass

View File

@ -2503,6 +2503,14 @@ class AllCallbacks(LiteLLMPydanticObjectBase):
ui_callback_name="Lago Billing",
)
traceloop: CallbackOnUI = CallbackOnUI(
litellm_callback_name="traceloop",
litellm_callback_params=[
"TRACELoop_API_KEY",
],
ui_callback_name="Traceloop",
)
class SpendLogsMetadata(TypedDict):
"""

View File

@ -153,6 +153,7 @@ from litellm.constants import (
)
from litellm.exceptions import RejectedRequestError
from litellm.integrations.SlackAlerting.slack_alerting import SlackAlerting
from litellm.integrations.custom_logger import CustomLogger
from litellm.litellm_core_utils.core_helpers import (
_get_parent_otel_span_from_kwargs,
get_litellm_metadata_from_kwargs,
@ -9575,35 +9576,7 @@ async def get_config(): # noqa: PLR0915
# Helper function to process callbacks and get environment variables
def process_callback(_callback: str, callback_type: str) -> dict:
"""Process a single callback and return its data with environment variables"""
if _callback == "langfuse" or _callback == "langfuse_otel":
env_vars = [
"LANGFUSE_PUBLIC_KEY",
"LANGFUSE_SECRET_KEY",
"LANGFUSE_HOST",
]
elif _callback == "openmeter":
env_vars = [
"OPENMETER_API_KEY",
]
elif _callback == "braintrust":
env_vars = [
"BRAINTRUST_API_KEY",
"BRAINTRUST_API_BASE",
]
elif _callback == "traceloop":
env_vars = ["TRACELOOP_API_KEY"]
elif _callback == "custom_callback_api":
env_vars = ["GENERIC_LOGGER_ENDPOINT"]
elif _callback == "otel":
env_vars = ["OTEL_EXPORTER", "OTEL_ENDPOINT", "OTEL_HEADERS"]
elif _callback == "langsmith":
env_vars = [
"LANGSMITH_API_KEY",
"LANGSMITH_PROJECT",
"LANGSMITH_DEFAULT_RUN_NAME",
]
else:
env_vars = []
env_vars = CustomLogger.get_callback_env_vars(_callback)
env_vars_dict = {}
for _var in env_vars:
@ -9625,7 +9598,7 @@ async def get_config(): # noqa: PLR0915
_success_callbacks = _litellm_settings.get("success_callback", [])
_failure_callbacks = _litellm_settings.get("failure_callback", [])
_generic_callbacks = _litellm_settings.get("callbacks", [])
_success_and_failure_callbacks = _litellm_settings.get("callbacks", [])
_data_to_return = []
"""
@ -9649,8 +9622,8 @@ async def get_config(): # noqa: PLR0915
for _callback in _failure_callbacks:
_data_to_return.append(process_callback(_callback, "failure"))
for _callback in _generic_callbacks:
_data_to_return.append(process_callback(_callback, "generic"))
for _callback in _success_and_failure_callbacks:
_data_to_return.append(process_callback(_callback, "success_and_failure"))
# Check if slack alerting is on
_alerting = _general_settings.get("alerting", [])

View File

@ -103,6 +103,24 @@ class TmpFunction:
)
def test_get_callback_env_vars():
env_vars = CustomLogger.get_callback_env_vars("langfuse")
assert env_vars == [
"LANGFUSE_PUBLIC_KEY",
"LANGFUSE_SECRET_KEY",
"LANGFUSE_HOST",
]
alias_env_vars = CustomLogger.get_callback_env_vars("langfuse_otel")
assert alias_env_vars == env_vars
missing_env_vars = CustomLogger.get_callback_env_vars("does_not_exist")
assert missing_env_vars == []
none_env_vars = CustomLogger.get_callback_env_vars(None)
assert none_env_vars == []
@pytest.mark.asyncio
async def test_async_chat_openai_stream():
try:

View File

@ -58,7 +58,7 @@ interface AlertingVariables {
interface AlertingObject {
name: string;
type?: "success" | "failure" | "generic";
type?: "success" | "failure" | "success_and_failure";
variables: AlertingVariables;
}
@ -430,17 +430,24 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
const tooltipMessage =
callback.type === "failure"
? "Modifications and deletion of failure type callbacks are not yet supported in the UI"
: callback.type === "generic"
? "Modifications and deletion of generic type callbacks are not yet supported in the UI"
: callback.type === "success_and_failure"
? "Modifications and deletion of success and failure type callbacks are not yet supported in the UI"
: "";
const getBadgeColor = (type?: string) => {
if (type === "success") return "green";
if (type === "failure") return "red";
if (type === "generic") return "blue";
if (type === "success_and_failure") return "blue";
return "gray";
};
const getBadgeLabel = (type?: string) => {
if (type === "success") return "Success Only";
if (type === "failure") return "Failure Only";
if (type === "success_and_failure") return "Success & Failure";
return "Unknown";
};
return (
<TableRow key={index}>
<TableCell>
@ -448,9 +455,9 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
</TableCell>
<TableCell>
{callback.type ? (
<Badge color={getBadgeColor(callback.type)}>{callback.type}</Badge>
<Badge color={getBadgeColor(callback.type)}>{getBadgeLabel(callback.type)}</Badge>
) : (
<Badge color="gray">success</Badge>
<Badge color="gray">Unknown</Badge>
)}
</TableCell>
<TableCell>