Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
ec004a5
feat(vertex_ai): propagate metadata labels to embedding, Imagen, rerank
Sameerlite Apr 2, 2026
5805609
Merge pull request #25521 from BerriAI/main
Sameerlite Apr 10, 2026
ebdc34e
Fix mypy
Sameerlite Apr 10, 2026
b19951a
Add litellm_metadata support
Sameerlite Apr 17, 2026
b594001
Merge pull request #25949 from BerriAI/litellm_internal_staging
Sameerlite Apr 17, 2026
2b028a6
Merge branch 'litellm_internal_staging' into litellm_vertex_request_m…
Sameerlite Apr 21, 2026
f4e976e
fix(anthropic): handle response_format tool alongside user tools in n…
Sameerlite Apr 22, 2026
47f46b4
Merge pull request #26304 from BerriAI/litellm_internal_staging
Sameerlite Apr 23, 2026
9d58e6e
Merge pull request #26379 from BerriAI/litellm_internal_staging
Sameerlite Apr 24, 2026
f503c06
Fix black formatting
Sameerlite Apr 24, 2026
be41d4b
Merge pull request #26437 from BerriAI/litellm_internal_staging
Sameerlite Apr 24, 2026
3337128
Fix black
Sameerlite Apr 27, 2026
09b648a
fix lint
Sameerlite Apr 27, 2026
3e1479c
Merge pull request #26731 from BerriAI/litellm_internal_staging
yuneng-berri Apr 29, 2026
d7862e7
Merge pull request #26745 from BerriAI/litellm_internal_staging
Sameerlite Apr 29, 2026
0166992
fix(proxy): contain UI_LOGO_PATH and LITELLM_FAVICON_URL to allowed a…
stuxf Apr 29, 2026
9ef8572
fix(proxy): /get_logo_url no longer discloses local UI_LOGO_PATH
stuxf Apr 29, 2026
4f751fd
fix(proxy): also accept LITELLM_ASSETS_PATH for /get_favicon local path
stuxf Apr 29, 2026
55d393d
fix(static-assets): unblock CI — pass headers explicitly + harden + u…
stuxf Apr 29, 2026
75d1a01
fix(static-assets): use async_safe_get; drop SVG; serve bytes inline …
stuxf Apr 29, 2026
c112bdf
chore(static-assets): /simplify pass — top-level Response import + cl…
stuxf Apr 29, 2026
89aa13f
fix(static-assets): also wrap admin-only Vault token verification in …
stuxf Apr 29, 2026
1277cbe
Add health status pagination controls
shivamrawat1 Apr 29, 2026
14473ed
fix(static-assets): ruff F811 — drop duplicate Response import
stuxf Apr 29, 2026
148485c
fix(passthrough): default auth=True; drop enterprise gate on the safe…
stuxf Apr 29, 2026
7c4ef97
fix(passthrough): drop now-unused CommonProxyErrors top-level import
stuxf Apr 29, 2026
0b9d06a
Fix model e2e result count locator
shivamrawat1 Apr 29, 2026
a7a3f0a
Address health pagination review feedback
shivamrawat1 Apr 29, 2026
88d8a80
tighten cli sso session flow
stuxf Apr 30, 2026
181e99b
Fix health pagination review issues
shivamrawat1 Apr 30, 2026
0f8dd28
lazy-load optional feature routers on first request
Apr 25, 2026
adcab43
swagger: stub-inject unloaded lazy features and warm on dropdown expand
Apr 28, 2026
1b9d216
add openapi snapshotting to CI pipeline
Apr 29, 2026
b3f3b11
address greptile fixes: shared _loaded state, auth on /lazy/warm, pin…
Apr 29, 2026
de75cd7
test_proxy_routes: dedupe lazy force-load to match vector_store test …
Apr 29, 2026
466ce9d
fix ruff: APIRouter type-checking import, replace print with sys.std*…
Apr 30, 2026
2612187
fix cli auth test expectations
stuxf Apr 30, 2026
19ca420
cover cli sso start validation
stuxf Apr 30, 2026
f3000bd
chore(mcp): encrypt user-scoped credentials at rest
stuxf Apr 30, 2026
6293252
harden cli sso review findings
stuxf Apr 30, 2026
c76c300
fix(mcp): address Greptile P2s on credential encoding helpers
stuxf Apr 30, 2026
8af0544
chore(mcp): tighten OAuth root endpoint resolution
stuxf Apr 30, 2026
8205e24
chore(auth): harden invite-link onboarding token flow
stuxf Apr 30, 2026
e0b32eb
fix(mcp): re-encrypt user credentials during master-key rotation
stuxf Apr 30, 2026
20b937d
chore(auth): address onboarding review follow-ups
stuxf Apr 30, 2026
d20d444
chore(auth): drop generated dashboard output
stuxf Apr 30, 2026
df62dd8
chore(mcp): SSRF guard on OAuth metadata discovery follow-up fetches
stuxf Apr 30, 2026
f2f1e3a
chore(proxy): block env callback refs in key metadata
stuxf Apr 30, 2026
4d056a1
test(proxy): cover callback env metadata rejection
stuxf Apr 30, 2026
1bb04cd
fix(mcp): close redirect bypass + empty-getaddrinfo gap on SSRF guard
stuxf Apr 30, 2026
22c01ad
chore(proxy): ignore invalid callback metadata rows
stuxf Apr 30, 2026
1ebb192
fix(proxy): catch callback metadata validation errors
stuxf Apr 30, 2026
e4c4d98
chore(team): close authz bypass via the available-team check
stuxf Apr 30, 2026
72674b0
test(team): add /team/permissions_update regression for available-tea…
stuxf Apr 30, 2026
2c4979e
Fix review
Sameerlite Apr 30, 2026
2c11fa0
chore(static-assets): keep vault tester out of asset hardening
stuxf Apr 30, 2026
adc2c55
chore(team): audit-log team-callback admin mutations
stuxf Apr 30, 2026
986cded
fix(audit): redact callback secrets and surface fire-and-forget failures
stuxf Apr 30, 2026
842eea0
chore(proxy): harden request control fields
stuxf Apr 30, 2026
7497674
fix(proxy): sanitize redaction controls at ingress
stuxf Apr 30, 2026
7c3c9ab
test(proxy): opt mock-response fixtures into client mocks
stuxf Apr 30, 2026
119c70b
fix(proxy): gate delegated audit attribution
stuxf Apr 30, 2026
db00e67
test(proxy): cover control field hardening branches
stuxf Apr 30, 2026
697331b
fix(proxy): apply audit attribution helper consistently
stuxf Apr 30, 2026
ea4e83e
fix(proxy): keep mcp audit attribution typed
stuxf Apr 30, 2026
c52be31
fix(logging): redact standard logging choice metadata
stuxf Apr 30, 2026
09c4d0d
fix(proxy): gate redaction opt out controls
stuxf Apr 30, 2026
609454d
Merge pull request #26852 from BerriAI/litellm_oss_staging
mateo-berri Apr 30, 2026
3bbb5c7
Remove dead _transform_response_for_json_mode wrapper
mateo-berri Apr 30, 2026
f48dfdb
fix(proxy): require opt in for audit header fallback
stuxf Apr 30, 2026
b5df9d9
test(vertex_ai): add e2e tests for rerank userLabels propagation
mateo-berri Apr 30, 2026
215f538
fix(static-assets): browser-load remote branding assets
stuxf Apr 30, 2026
b8a141c
fix(static-assets): stop serving stale logo cache
stuxf Apr 30, 2026
d47948a
fix: validate aws region name
yassinkortam Apr 30, 2026
21c7864
Fix Vertex label metadata fallback
cursoragent Apr 30, 2026
d51d96f
Merge pull request #26859 from stuxf/chore/audit-log-team-callback-mu…
yuneng-berri Apr 30, 2026
b67a81d
test(proxy): align favicon remote asset expectations
stuxf Apr 30, 2026
0efa8b8
Merge pull request #26854 from stuxf/fix/team-authz-available-team-by…
yuneng-berri Apr 30, 2026
dfc080f
fix: drop milvus dbName and partitionNames from MILVUS_OPTIONAL_PARAMS
yassinkortam Apr 30, 2026
a9db887
Merge pull request #26843 from stuxf/codex/fix-onboarding-invite-token
yuneng-berri Apr 30, 2026
3c06036
Merge pull request #26840 from stuxf/codex/mcp-oauth-root-visibility
yuneng-berri Apr 30, 2026
51a3e90
fix(mcp): reuse safe URL fetch for OAuth discovery
stuxf Apr 30, 2026
d84b35c
Merge pull request #26906 from BerriAI/litellm_fix/validate-aws-region
yassin-berriai Apr 30, 2026
08541f4
Merge pull request #26910 from BerriAI/litellm_fix/drop-milvus-db-params
yuneng-berri Apr 30, 2026
9637d8c
Merge pull request #26802 from BerriAI/litellm_lazyLoadedFrontPage
Michael-RZ-Berri Apr 30, 2026
aa76ab2
Merge pull request #26862 from stuxf/codex/control-field-sanitization
yuneng-berri Apr 30, 2026
4ff8f0e
Merge pull request #26851 from stuxf/codex/fix-callback-env-secret-re…
yuneng-berri Apr 30, 2026
174c770
Merge pull request #26836 from stuxf/fix/byok-credential-encryption
yuneng-berri Apr 30, 2026
256e05e
Merge pull request #26849 from stuxf/fix/mcp-oauth-discovery-ssrf
yuneng-berri Apr 30, 2026
47b2832
test: replace subprocess startup-import diff with static source scan
Apr 30, 2026
e810d87
Merge pull request #26934 from BerriAI/litellm_lazyStartupTestFix
Michael-RZ-Berri Apr 30, 2026
053e040
run pre_call_hook on Google generateContent endpoints
Apr 30, 2026
be0e991
[Test] Proxy E2E: Opt In To Client Mock Response For Model Access Tests
yuneng-berri May 1, 2026
71d5015
Merge pull request #26827 from stuxf/fix/passthrough-auth-default
yuneng-berri May 1, 2026
15b7386
Merge pull request #26815 from stuxf/fix/get-image-lfi-ssrf
yuneng-berri May 1, 2026
bdcc238
Merge pull request #26835 from stuxf/codex/cli-sso-flow-binding
yuneng-berri May 1, 2026
326bcd6
Merge pull request #26941 from BerriAI/litellm_/stoic-jemison-cbb6cf
yuneng-berri May 1, 2026
bd63824
[Fix] Responses API: Omit Empty Body On DELETE
yuneng-berri May 1, 2026
76e43b7
Merge pull request #26949 from BerriAI/litellm_/condescending-hawking…
ryan-crabbe-berri May 1, 2026
9f08db9
Refresh Redis TTL on counter writes and skip stale in-memory on Redis…
Apr 29, 2026
fed5f36
Invalidate spend counters on budget reset
Apr 29, 2026
ff2a938
Match docstring style on async_increment_cache
Apr 29, 2026
4e26835
Reorder counter invalidation to run after DB write
Apr 30, 2026
e4fb325
Merge pull request #26914 from BerriAI/litellm_googleGenContentHooks
Michael-RZ-Berri May 1, 2026
05e6402
Merge pull request #26829 from BerriAI/litellm_budgetEnforcementMultiPod
Michael-RZ-Berri May 1, 2026
ebbe2f4
Merge pull request #26826 from BerriAI/litellm_health_status_pagination
yuneng-berri May 1, 2026
72ddbce
Merge pull request #25499 from BerriAI/litellm_vertex_request_metadat…
Sameerlite May 1, 2026
efa33bf
Merge pull request #26222 from BerriAI/litellm_anthropic-json-mode-no…
Sameerlite May 1, 2026
dd549d9
bump: version 0.4.69 → 0.4.70
yuneng-berri May 1, 2026
6da13ef
uv lock
yuneng-berri May 1, 2026
9397409
Merge pull request #26961 from BerriAI/yj_bump_apr30
shin-berri May 1, 2026
934ecdc
Merge pull request #26962 from BerriAI/litellm_internal_staging
yuneng-berri May 1, 2026
4ba0b46
feat: add Cortecs AI as OpenAI-compatible provider
May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/check-lazy-openapi-snapshot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Check Lazy OpenAPI Snapshot

on:
pull_request:
branches:
- main
- litellm_internal_staging
- "litellm_**"

permissions:
contents: read
checks: write

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"

- name: Set up uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
with:
version: "0.10.9"

- name: Cache uv dependencies
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-

- name: Install dependencies
run: uv sync --frozen --all-groups --all-extras

- name: Regenerate snapshot to /tmp
id: regen
run: |
cp litellm/proxy/_lazy_openapi_snapshot.json /tmp/snapshot.committed.json
uv run --no-sync python -m litellm.proxy._lazy_openapi_snapshot
mv litellm/proxy/_lazy_openapi_snapshot.json /tmp/snapshot.fresh.json
mv /tmp/snapshot.committed.json litellm/proxy/_lazy_openapi_snapshot.json

- name: Compare
id: diff
continue-on-error: true
run: |
diff -q /tmp/snapshot.fresh.json litellm/proxy/_lazy_openapi_snapshot.json

- name: Mark neutral if drift
if: steps.diff.outcome == 'failure'
uses: LouisBrunner/checks-action@6b626ffbad7cc56fd58627f774b9067e6118af23 # v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: lazy-openapi-snapshot
conclusion: neutral
output: |
{
"title": "Lazy openapi snapshot is stale",
"summary": "Run `python -m litellm.proxy._lazy_openapi_snapshot` and commit the regenerated `litellm/proxy/_lazy_openapi_snapshot.json`. Not blocking — the snapshot will regenerate at release if not committed."
}
4 changes: 2 additions & 2 deletions litellm-proxy-extras/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "litellm-proxy-extras"
version = "0.4.69"
version = "0.4.70"
description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package."
readme = "README.md"
requires-python = ">=3.9"
Expand All @@ -26,7 +26,7 @@ required-version = ">=0.10.9"
module-root = ""

[tool.commitizen]
version = "0.4.69"
version = "0.4.70"
version_files = [
"pyproject.toml:^version",
"../pyproject.toml:litellm-proxy-extras==",
Expand Down
5 changes: 5 additions & 0 deletions litellm/caching/dual_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,17 @@ async def async_increment_cache(
value: float,
parent_otel_span: Optional[Span] = None,
local_only: bool = False,
refresh_ttl: bool = False,
**kwargs,
) -> Optional[float]:
"""
Key - the key in cache

Value - float - the value you want to increment by

Refresh_ttl - bool - if True, resets the Redis TTL on every write.
Default False preserves window-style semantics.

Returns - the incremented value, or None if no cache backend is
available (in_memory_cache is None and Redis failed/is absent).
"""
Expand All @@ -415,6 +419,7 @@ async def async_increment_cache(
value,
parent_otel_span=parent_otel_span,
ttl=kwargs.get("ttl", None),
refresh_ttl=refresh_ttl,
)

return result
Expand Down
10 changes: 6 additions & 4 deletions litellm/caching/redis_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ async def async_increment(
value: float,
ttl: Optional[int] = None,
parent_otel_span: Optional[Span] = None,
refresh_ttl: bool = False,
) -> float:
from redis.asyncio import Redis

Expand All @@ -834,11 +835,12 @@ async def async_increment(
try:
result = await _redis_client.incrbyfloat(name=key, amount=value)
if _used_ttl is not None:
# check if key already has ttl, if not -> set ttl
current_ttl = await _redis_client.ttl(key)
if current_ttl == -1:
# Key has no expiration
if refresh_ttl:
await _redis_client.expire(key, _used_ttl)
else:
current_ttl = await _redis_client.ttl(key)
if current_ttl == -1:
await _redis_client.expire(key, _used_ttl)

## LOGGING ##
end_time = time.time()
Expand Down
1 change: 1 addition & 0 deletions litellm/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,7 @@
LITELLM_CLI_SOURCE_IDENTIFIER = "litellm-cli"
LITELLM_CLI_SESSION_TOKEN_PREFIX = "litellm-session-token"
CLI_SSO_SESSION_CACHE_KEY_PREFIX = "cli_sso_session"
CLI_SSO_SESSION_TTL_SECONDS = 600
CLI_JWT_TOKEN_NAME = "cli-jwt-token"
# Support both CLI_JWT_EXPIRATION_HOURS and LITELLM_CLI_JWT_EXPIRATION_HOURS for backwards compatibility
CLI_JWT_EXPIRATION_HOURS = int(
Expand Down
17 changes: 13 additions & 4 deletions litellm/litellm_core_utils/initialize_dynamic_callback_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ def _raise_env_reference_error(param: str, *, source: str) -> None:
)


def validate_no_callback_env_reference(
param: str, value: object, *, source: str
) -> None:
if _is_env_reference(value):
_raise_env_reference_error(param, source=source)


# Hardcoded list of supported callback params to avoid runtime inspection issues with TypedDict
_supported_callback_params = [
"langfuse_public_key",
Expand Down Expand Up @@ -66,8 +73,9 @@ def initialize_standard_callback_dynamic_params(
for param in _supported_callback_params:
if param in kwargs:
_param_value = kwargs.get(param)
if _is_env_reference(_param_value):
_raise_env_reference_error(param, source="request body")
validate_no_callback_env_reference(
param, _param_value, source="request body"
)
standard_callback_dynamic_params[param] = _param_value # type: ignore

# 2. Fallback: check "metadata" or "litellm_params" -> "metadata"
Expand All @@ -80,8 +88,9 @@ def initialize_standard_callback_dynamic_params(
for param in _supported_callback_params:
if param not in standard_callback_dynamic_params and param in metadata:
_param_value = metadata.get(param)
if _is_env_reference(_param_value):
_raise_env_reference_error(param, source="metadata")
validate_no_callback_env_reference(
param, _param_value, source="metadata"
)
standard_callback_dynamic_params[param] = _param_value # type: ignore

return standard_callback_dynamic_params
102 changes: 59 additions & 43 deletions litellm/litellm_core_utils/redact_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def _redact_choice_content(choice):
def _redact_responses_api_output(output_items):
"""Helper to redact ResponsesAPIResponse output items."""
for output_item in output_items:
if hasattr(output_item, "text"):
output_item.text = "redacted-by-litellm"

if hasattr(output_item, "content") and isinstance(output_item.content, list):
for content_part in output_item.content:
if hasattr(content_part, "text"):
Expand All @@ -75,6 +78,28 @@ def _redact_responses_api_output(output_items):
summary_item.text = "redacted-by-litellm"


def _redact_responses_api_output_dict(output_items, redacted_str: str):
"""Helper to redact ResponsesAPIResponse output items in dict form."""
for output_item in output_items:
if not isinstance(output_item, dict):
continue

if "text" in output_item:
output_item["text"] = redacted_str

if isinstance(output_item.get("content"), list):
for content_item in output_item["content"]:
if isinstance(content_item, dict) and "text" in content_item:
content_item["text"] = redacted_str

if output_item.get("type") == "reasoning" and isinstance(
output_item.get("summary"), list
):
for summary_item in output_item["summary"]:
if isinstance(summary_item, dict) and "text" in summary_item:
summary_item["text"] = redacted_str


def _redact_standard_logging_object(model_call_details: dict):
"""Redact messages and response inside standard_logging_object if present."""
standard_logging_object = model_call_details.get("standard_logging_object")
Expand All @@ -93,35 +118,41 @@ def _redact_standard_logging_object(model_call_details: dict):
if isinstance(response, dict) and "output" in response:
# ResponsesAPIResponse format - redact content in output items
if isinstance(response.get("output"), list):
for output_item in response["output"]:
if isinstance(output_item, dict) and "content" in output_item:
if isinstance(output_item["content"], list):
for content_item in output_item["content"]:
if (
isinstance(content_item, dict)
and "text" in content_item
):
content_item["text"] = redacted_str
_redact_responses_api_output_dict(response["output"], redacted_str)
elif isinstance(response, dict) and "choices" in response:
# ModelResponse dict format - redact content in choices
if isinstance(response.get("choices"), list):
for choice in response["choices"]:
if isinstance(choice, dict):
if "message" in choice and isinstance(choice["message"], dict):
choice["message"]["content"] = redacted_str
if "audio" in choice["message"]:
choice["message"]["audio"] = None
elif "delta" in choice and isinstance(choice["delta"], dict):
choice["delta"]["content"] = redacted_str
if "audio" in choice["delta"]:
choice["delta"]["audio"] = None
_redact_model_response_dict_choices(response["choices"], redacted_str)
elif isinstance(response, str):
standard_logging_object["response"] = redacted_str
else:
# For other formats (empty dict, None, etc.), use simple text format
standard_logging_object["response"] = {"text": redacted_str}


def _redact_model_response_dict_choices(choices, redacted_str: str):
for choice in choices:
if isinstance(choice, dict):
if "message" in choice and isinstance(choice["message"], dict):
choice["message"]["content"] = redacted_str
if "reasoning_content" in choice["message"]:
choice["message"]["reasoning_content"] = redacted_str
if "thinking_blocks" in choice["message"]:
choice["message"]["thinking_blocks"] = None
if "audio" in choice["message"]:
choice["message"]["audio"] = None
elif "delta" in choice and isinstance(choice["delta"], dict):
choice["delta"]["content"] = redacted_str
if "reasoning_content" in choice["delta"]:
choice["delta"]["reasoning_content"] = redacted_str
if "thinking_blocks" in choice["delta"]:
choice["delta"]["thinking_blocks"] = None
if "audio" in choice["delta"]:
choice["delta"]["audio"] = None
else:
_redact_choice_content(choice)


def perform_redaction(model_call_details: dict, result):
"""
Performs the actual redaction on the logging object and result.
Expand All @@ -132,6 +163,7 @@ def perform_redaction(model_call_details: dict, result):
]
model_call_details["prompt"] = ""
model_call_details["input"] = ""
_redact_standard_logging_object(model_call_details)

# Redact streaming response
if (
Expand Down Expand Up @@ -171,30 +203,14 @@ def perform_redaction(model_call_details: dict, result):
elif isinstance(_result, dict) and "choices" in _result:
# Handle dict representation of ModelResponse (e.g., from model_dump())
if _result.get("choices") is not None:
for choice in _result["choices"]:
if isinstance(choice, dict):
if "message" in choice and isinstance(choice["message"], dict):
choice["message"]["content"] = "redacted-by-litellm"
if "reasoning_content" in choice["message"]:
choice["message"][
"reasoning_content"
] = "redacted-by-litellm"
if "thinking_blocks" in choice["message"]:
choice["message"]["thinking_blocks"] = None
if "audio" in choice["message"]:
choice["message"]["audio"] = None
elif "delta" in choice and isinstance(choice["delta"], dict):
choice["delta"]["content"] = "redacted-by-litellm"
if "reasoning_content" in choice["delta"]:
choice["delta"][
"reasoning_content"
] = "redacted-by-litellm"
if "thinking_blocks" in choice["delta"]:
choice["delta"]["thinking_blocks"] = None
if "audio" in choice["delta"]:
choice["delta"]["audio"] = None
else:
_redact_choice_content(choice)
_redact_model_response_dict_choices(
_result["choices"], "redacted-by-litellm"
)
elif isinstance(_result, dict) and "output" in _result:
if isinstance(_result.get("output"), list):
_redact_responses_api_output_dict(
_result["output"], "redacted-by-litellm"
)
elif isinstance(_result, litellm.ResponsesAPIResponse):
if hasattr(_result, "output"):
_redact_responses_api_output(_result.output)
Expand Down
Loading
Loading