mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
Merge e8e08b63f0 into 74050e03c5
This commit is contained in:
commit
720d2810f3
6 changed files with 144 additions and 1 deletions
|
|
@ -2585,6 +2585,10 @@ class ConfigGeneralSettings(LiteLLMPydanticObjectBase):
|
|||
None,
|
||||
description="If True, stores request messages and responses in spend logs. Default is False.",
|
||||
)
|
||||
store_responses_in_spend_logs: bool | None = Field(
|
||||
None,
|
||||
description="Controls response content storage in spend logs independently. When unset, follows store_prompts_in_spend_logs for backward compatibility.",
|
||||
)
|
||||
disable_auto_add_proxy_admin_to_teams: bool | None = Field(
|
||||
None,
|
||||
description="By default, the user calling /team/new is automatically added to the new team as a team admin. If True, proxy admins are no longer auto-added; members explicitly listed in members_with_roles are unaffected. Default is False.",
|
||||
|
|
|
|||
|
|
@ -6546,6 +6546,21 @@ class ProxyConfig:
|
|||
# For other types, convert to bool
|
||||
general_settings["store_prompts_in_spend_logs"] = bool(value)
|
||||
|
||||
if "store_responses_in_spend_logs" in _general_settings:
|
||||
response_storage_value: Final = (
|
||||
general_settings.get("store_responses_in_spend_logs")
|
||||
if "store_responses_in_spend_logs" in self._yaml_general_settings_keys
|
||||
else _general_settings["store_responses_in_spend_logs"]
|
||||
)
|
||||
if response_storage_value is None:
|
||||
general_settings["store_responses_in_spend_logs"] = None
|
||||
elif isinstance(response_storage_value, bool):
|
||||
general_settings["store_responses_in_spend_logs"] = response_storage_value
|
||||
elif isinstance(response_storage_value, str):
|
||||
general_settings["store_responses_in_spend_logs"] = response_storage_value.lower() == "true"
|
||||
else:
|
||||
general_settings["store_responses_in_spend_logs"] = bool(response_storage_value)
|
||||
|
||||
if "disable_auto_add_proxy_admin_to_teams" in _general_settings:
|
||||
value = _general_settings["disable_auto_add_proxy_admin_to_teams"]
|
||||
if isinstance(value, str):
|
||||
|
|
@ -16061,6 +16076,7 @@ _GENERAL_SETTINGS_CONFIG_LIST_FIELD_TYPES: Final[Mapping[str, str]] = MappingPro
|
|||
"pass_through_endpoints": "PydanticModel",
|
||||
"store_model_in_db": "Boolean",
|
||||
"store_prompts_in_spend_logs": "Boolean",
|
||||
"store_responses_in_spend_logs": "Boolean",
|
||||
"maximum_spend_logs_retention_period": "String",
|
||||
"maximum_health_check_retention_period": "String",
|
||||
"maximum_spend_logs_cleanup_batch_size": "Integer",
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ def _get_response_for_spend_logs_payload(
|
|||
) -> str:
|
||||
if payload is None:
|
||||
return "{}"
|
||||
if _should_store_prompts_and_responses_in_spend_logs():
|
||||
if _should_store_responses_in_spend_logs():
|
||||
response_obj: Any = payload.get("response")
|
||||
if response_obj is None:
|
||||
return "{}"
|
||||
|
|
@ -1236,6 +1236,18 @@ def _should_store_prompts_and_responses_in_spend_logs() -> bool:
|
|||
return get_secret_bool("STORE_PROMPTS_IN_SPEND_LOGS") is True
|
||||
|
||||
|
||||
def _should_store_responses_in_spend_logs() -> bool:
|
||||
from litellm.proxy.proxy_server import general_settings
|
||||
|
||||
store_responses_value: Final = general_settings.get("store_responses_in_spend_logs")
|
||||
if store_responses_value is not None:
|
||||
if isinstance(store_responses_value, str):
|
||||
return store_responses_value.lower() == "true"
|
||||
return store_responses_value is True
|
||||
|
||||
return _should_store_prompts_and_responses_in_spend_logs()
|
||||
|
||||
|
||||
def _get_status_for_spend_log(
|
||||
metadata: dict,
|
||||
) -> Literal["success", "failure"]:
|
||||
|
|
|
|||
|
|
@ -353,3 +353,40 @@ class TestYamlStorePromptsDbOverride:
|
|||
"""_yaml_general_settings_keys should be empty on init."""
|
||||
proxy_config = ProxyConfig()
|
||||
assert proxy_config._yaml_general_settings_keys == set()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_response_storage_yaml_value_takes_precedence_over_db(self):
|
||||
proxy_config = self._make_proxy_config_with_yaml_keys({"store_responses_in_spend_logs"})
|
||||
test_general_settings = {"store_responses_in_spend_logs": False}
|
||||
|
||||
with mock.patch("litellm.proxy.proxy_server.general_settings", test_general_settings):
|
||||
await proxy_config._update_general_settings(
|
||||
db_general_settings={"store_responses_in_spend_logs": True},
|
||||
)
|
||||
|
||||
assert test_general_settings["store_responses_in_spend_logs"] is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("db_value", "expected"),
|
||||
[
|
||||
(None, None),
|
||||
(True, True),
|
||||
("TRUE", True),
|
||||
(0, False),
|
||||
],
|
||||
)
|
||||
async def test_response_storage_db_value_is_normalized_when_yaml_omits_key(
|
||||
self,
|
||||
db_value,
|
||||
expected,
|
||||
):
|
||||
proxy_config = self._make_proxy_config_with_yaml_keys({"master_key"})
|
||||
test_general_settings = {"master_key": "sk-test"}
|
||||
|
||||
with mock.patch("litellm.proxy.proxy_server.general_settings", test_general_settings):
|
||||
await proxy_config._update_general_settings(
|
||||
db_general_settings={"store_responses_in_spend_logs": db_value},
|
||||
)
|
||||
|
||||
assert test_general_settings["store_responses_in_spend_logs"] is expected
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ from litellm.proxy.spend_tracking.spend_tracking_utils import (
|
|||
_sanitize_guardrail_information_for_spend_logs,
|
||||
_sanitize_request_body_for_spend_logs_payload,
|
||||
_should_store_prompts_and_responses_in_spend_logs,
|
||||
_should_store_responses_in_spend_logs,
|
||||
get_logging_payload,
|
||||
get_spend_logs_id,
|
||||
)
|
||||
|
|
@ -1440,6 +1441,74 @@ def test_should_store_prompts_and_responses_in_spend_logs_case_insensitive_strin
|
|||
), "Expected False (from env var) when key missing, got True"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("settings", "expected"),
|
||||
[
|
||||
({"store_prompts_in_spend_logs": True}, True),
|
||||
({"store_prompts_in_spend_logs": False}, False),
|
||||
(
|
||||
{
|
||||
"store_prompts_in_spend_logs": True,
|
||||
"store_responses_in_spend_logs": False,
|
||||
},
|
||||
False,
|
||||
),
|
||||
(
|
||||
{
|
||||
"store_prompts_in_spend_logs": False,
|
||||
"store_responses_in_spend_logs": True,
|
||||
},
|
||||
True,
|
||||
),
|
||||
(
|
||||
{
|
||||
"store_prompts_in_spend_logs": True,
|
||||
"store_responses_in_spend_logs": "FALSE",
|
||||
},
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_should_store_responses_in_spend_logs(
|
||||
settings,
|
||||
expected,
|
||||
):
|
||||
with patch("litellm.proxy.proxy_server.general_settings", settings):
|
||||
assert _should_store_responses_in_spend_logs() is expected
|
||||
|
||||
|
||||
def test_spend_logs_can_store_request_without_response():
|
||||
settings = {
|
||||
"store_prompts_in_spend_logs": True,
|
||||
"store_responses_in_spend_logs": False,
|
||||
}
|
||||
kwargs = {
|
||||
"litellm_params": {
|
||||
"proxy_server_request": {
|
||||
"body": {
|
||||
"model": "gpt-5-mini",
|
||||
"messages": [{"role": "user", "content": "Hello!"}],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
payload = cast(
|
||||
StandardLoggingPayload,
|
||||
{"response": {"role": "assistant", "content": "Hi there!"}},
|
||||
)
|
||||
|
||||
with patch("litellm.proxy.proxy_server.general_settings", settings):
|
||||
request_result = _get_proxy_server_request_for_spend_logs_payload(
|
||||
metadata={},
|
||||
litellm_params=kwargs["litellm_params"],
|
||||
kwargs=kwargs,
|
||||
)
|
||||
response_result = _get_response_for_spend_logs_payload(payload=payload, kwargs=kwargs)
|
||||
|
||||
assert json.loads(request_result)["messages"] == [{"role": "user", "content": "Hello!"}]
|
||||
assert response_result == "{}"
|
||||
|
||||
|
||||
def test_get_spend_logs_metadata_guardrail_info_fallback_from_metadata():
|
||||
"""
|
||||
When standard_logging_payload is None (e.g. guardrail blocks before LLM call),
|
||||
|
|
|
|||
5
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
5
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
|
|
@ -25152,6 +25152,11 @@ export interface components {
|
|||
* @description If True, stores request messages and responses in spend logs. Default is False.
|
||||
*/
|
||||
store_prompts_in_spend_logs?: boolean | null;
|
||||
/**
|
||||
* Store Responses In Spend Logs
|
||||
* @description Controls response content storage in spend logs independently. When unset, follows store_prompts_in_spend_logs for backward compatibility.
|
||||
*/
|
||||
store_responses_in_spend_logs?: boolean | null;
|
||||
/**
|
||||
* Supported Db Objects
|
||||
* @description Fine-grained control over which object types to load from the database when store_model_in_db is True. Available types: 'models', 'mcp', 'guardrails', 'vector_stores', 'pass_through_endpoints', 'prompts', 'model_cost_map', 'tools', 'config_overrides'. If not set, all objects are loaded (default behavior).
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue