litellm/tests/unit/llms/gemini
devin-ai-integration[bot] 859529ccbc
fix(realtime)!: keep turn_detection.type when a transcript guardrail disables auto-response (#44939)
* fix(realtime): keep turn_detection.type when a transcript guardrail disables auto-response

* test(realtime): type the GA session.update helper and mark its locals Final

* test(realtime): expect typed turn_detection on the voice guardrail session updates

* test(realtime): accept either gate path for the client's first voice session.update

* fix(gemini): drop VAD tuning when the guardrail turns auto-response off

* fix(gemini): check create_response without a redundant isinstance

* fix(vertex_ai): keep the client's VAD tuning on Vertex when auto-response is off

* fix(realtime): keep the transcript-guardrail gate typeless on xAI so it does not auto-answer

* fix(realtime): replace any client turn_detection with the untyped gate on xAI

xAI answers on its own under a typed server_vad even with create_response off,
so a client's typed turn_detection must not reach xAI while the transcript
guardrail gates the turn.

* fix(realtime): keep a client's early turn_detection and hide the guardrail cancel's error

A session.update sent before session.created reached OpenAI ahead of the proxy's own gate, so the gate replaced the client's turn_detection. The proxy now re-sends the client's gated turn_detection after the gate when the two differ.

The guardrail's response.cancel now carries a litellm_guardrail_ event_id, and the error OpenAI returns for it (response_cancel_not_active when nothing is answering) no longer reaches the client.

* fix(realtime): send the guardrail gate before a client's early session.update and let Muse and Chirp fall back to server_vad under drop_params

* fix(realtime): hide only the cancel errors that echo the guardrail's own response.cancel ids

Track the event ids of the guardrail cancels this session sent and drop a backend error only when its
error.event_id is one of them, so a client's own event id with the same prefix still gets its error.
Cover the scripted response.cancel reply in the integration upstream, update the stale list-mode test
to the typed gate, and mark the xAI cancel error cell as an expected failure, since xAI replies with
its own event id.

* test(integration support): deliver the disconnect a real server sends after the client goes away

The scripted upstream now keeps reading frames after a reply hits a closed socket, so the unit test's
fake ASGI receive has to end with the websocket.disconnect message a real server delivers.

* fix(realtime): delete the blocked transcript item before the guardrail's refusal turn

OpenAI GA answered the blocked question in some refusal turns because the
blocked user item stayed in the conversation. The raw OpenAI-protocol path
now sends conversation.item.delete for it right after the cancel. Provider
config backends have no such event, so that path no longer passes an item id.

Also bound the guardrail integration file by the shared graceful-stop
timeout and make the xAI cancel-error xfail require an AssertionError.

* fix(realtime): keep the blocked item on xAI, which cannot delete an audio input item

* test(realtime): assert the xAI voice block sends no conversation.item.delete upstream

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-10-16 15:24:40 +00:00
..
audio_transcription test(unit): make every tests/unit directory a package so pytest collection is unique 2026-09-20 11:50:59 +00:00
files test(unit): make every tests/unit directory a package so pytest collection is unique 2026-09-20 11:50:59 +00:00
google_genai test: migrate SDK and proxy-booting legacy CircleCI tests to their tiers (#45758) 2026-10-11 00:17:21 -07:00
image_edit test(unit): make every tests/unit directory a package so pytest collection is unique 2026-09-20 11:50:59 +00:00
image_generation test: move whole-unit legacy test files into tests/unit and delete dead skips (#44807) 2026-10-07 05:02:28 +00:00
realtime fix(realtime)!: keep turn_detection.type when a transcript guardrail disables auto-response (#44939) 2026-10-16 15:24:40 +00:00
videos test(unit): make every tests/unit directory a package so pytest collection is unique 2026-09-20 11:50:59 +00:00
__init__.py test(unit): make every tests/unit directory a package so pytest collection is unique 2026-09-20 11:50:59 +00:00
test_cost_calculator.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
test_gemini_client_setup.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
test_gemini_common_utils.py fix(count_tokens): count Anthropic-format requests for Gemini the way /v1/messages inference converts them (#46767) 2026-10-16 02:32:24 +00:00
test_gemini_image_generation_transformation.py chore(typing): clear 670 basedpyright Any errors by validating provider payloads at the boundary (#45388) 2026-10-13 15:35:23 -07:00
test_gemini_streaming.py test: migrate local_testing SDK and provider tests out of build_and_test (#45760) 2026-10-10 23:14:25 +00:00
test_gemini_tts.py refactor(llms): expose public names for private provider helpers (#45037) 2026-10-07 08:49:25 -07:00
test_image_usage_transformation.py refactor(types): replace Any with proven types in 157 files (#44798) 2026-10-06 15:31:54 +00:00