Python 88.3%
TypeScript 7.6%
Shell 4.1%
1"""Thinking: thinkingBudget/includeThoughts (gemini-3.5-flash), thinkingLevel (gemini-3.8-flash), conflicts. Verified 2026-09-18.23The two thinking-model calls cost ~ $0.0015 together; gated behind RUN_EXPENSIVE_TESTS like other thinking tests.4"""5from __future__ import annotations67import pytest89from tests.gemini._core_helpers import call, gc, user1011FLASH = "gemini-3.5-flash"12G38 = "gemini-3.8-flash"131415@pytest.mark.run_expensive_tests16def test_thinking_budget_include_thoughts(gemini):17 st, r, _ = call(gemini, "POST", gc(FLASH), {"contents": user("What is 17*23? Reply with the number only."), "generationConfig": {"maxOutputTokens": 600, "thinkingConfig": {"thinkingBudget": 256, "includeThoughts": True}}}, timeout=180, note="test_thinking budget+thoughts")18 assert st == 200, r19 parts = r["candidates"][0]["content"]["parts"]20 assert r["usageMetadata"]["thoughtsTokenCount"] > 021 assert "391" in "".join(p.get("text", "") for p in parts if not p.get("thought"))22 assert parts[-1].get("thoughtSignature")23 if any(p.get("thought") for p in parts):24 assert parts[0]["thought"] is True, "thought summary parts come first"252627@pytest.mark.run_expensive_tests28def test_thinking_level_low_and_minimal_error(gemini):29 st, r, _ = call(gemini, "POST", gc(G38), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 64, "thinkingConfig": {"thinkingLevel": "low"}}}, timeout=180, note="test_thinking level low")30 assert st == 200 and "OK" in r["candidates"][0]["content"]["parts"][0]["text"]31 st, r, _ = call(gemini, "POST", gc(G38), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16, "thinkingConfig": {"thinkingLevel": "minimal"}}}, note="test_thinking level minimal")32 assert st == 400 and "MINIMAL is not supported" in r["error"]["message"]333435def test_conflicts_and_ranges_cheap(gemini, models):36 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16, "thinkingConfig": {"thinkingLevel": "low", "thinkingBudget": 100}}}, note="test_thinking level+budget")37 assert st == 400 and "only one of thinking budget and thinking level" in r["error"]["message"]38 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16, "thinkingConfig": {"thinkingBudget": 100000}}}, note="test_thinking budget range")39 assert st == 400 and "[-1, 65535]" in r["error"]["message"]40 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16, "thinkingConfig": {"thinkingBudget": 0}}}, note="test_thinking flash-lite budget 0")41 assert st == 400, "3.5 Flash-Lite cannot disable thinking via budget 0"42 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16, "thinkingConfig": {"thinkingLevel": "minimal"}}}, note="test_thinking flash-lite minimal")43 assert st == 200 and "thoughtsTokenCount" not in r["usageMetadata"]444546def test_thought_signature_roundtrip_and_corruption(gemini, models):47 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 8}}, note="test_thinking sig get")48 assert st == 20049 parts = r["candidates"][0]["content"]["parts"]50 hist = [{"role": "user", "parts": [{"text": "Reply with OK."}]}, {"role": "model", "parts": parts}, {"role": "user", "parts": [{"text": "Again, reply with OK."}]}]51 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": hist, "generationConfig": {"maxOutputTokens": 8}}, note="test_thinking sig roundtrip")52 assert st == 200, r53 bad = [{"role": "user", "parts": [{"text": "Reply with OK."}]}, {"role": "model", "parts": [{"text": "OK.", "thoughtSignature": "bm90LWEtcmVhbC1zaWc="}]}, {"role": "user", "parts": [{"text": "Again."}]}]54 st, r, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": bad, "generationConfig": {"maxOutputTokens": 8}}, note="test_thinking sig corrupted")55 assert st == 400 and "Corrupted thought signature" in r["error"]["message"]56