|
32 | 32 |
|
33 | 33 |
|
34 | 34 | def test_process_thinking_budget(): |
35 | | - """Test the _process_thinking_config method with different thinking_budget values.""" |
| 35 | + """Test the _process_thinking_config function with different thinking_budget values.""" |
36 | 36 |
|
37 | 37 | # Test valid thinking_budget values |
38 | 38 | generation_kwargs = {"thinking_budget": 1024, "temperature": 0.7} |
39 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 39 | + result = _process_thinking_config(generation_kwargs) |
40 | 40 |
|
41 | 41 | # thinking_budget should be moved to thinking_config |
42 | 42 | assert "thinking_budget" not in result |
43 | 43 | assert "thinking_config" in result |
44 | 44 | assert result["thinking_config"].thinking_budget == 1024 |
| 45 | + assert result["thinking_config"].include_thoughts is True |
45 | 46 | # Other kwargs should be preserved |
46 | 47 | assert result["temperature"] == 0.7 |
47 | 48 |
|
48 | 49 | # Test dynamic allocation (-1) |
49 | 50 | generation_kwargs = {"thinking_budget": -1} |
50 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 51 | + result = _process_thinking_config(generation_kwargs) |
51 | 52 | assert result["thinking_config"].thinking_budget == -1 |
| 53 | + assert result["thinking_config"].include_thoughts is True |
52 | 54 |
|
53 | 55 | # Test zero (disable thinking) |
54 | 56 | generation_kwargs = {"thinking_budget": 0} |
55 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 57 | + result = _process_thinking_config(generation_kwargs) |
56 | 58 | assert result["thinking_config"].thinking_budget == 0 |
| 59 | + assert result["thinking_config"].include_thoughts is False |
57 | 60 |
|
58 | 61 | # Test large value |
59 | 62 | generation_kwargs = {"thinking_budget": 24576} |
60 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 63 | + result = _process_thinking_config(generation_kwargs) |
61 | 64 | assert result["thinking_config"].thinking_budget == 24576 |
| 65 | + assert result["thinking_config"].include_thoughts is True |
62 | 66 |
|
63 | 67 | # Test when thinking_budget is not present |
64 | 68 | generation_kwargs = {"temperature": 0.5} |
65 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 69 | + result = _process_thinking_config(generation_kwargs) |
66 | 70 | assert result == generation_kwargs # No changes |
67 | 71 |
|
68 | 72 | # Test invalid type (should fall back to dynamic) |
69 | 73 | generation_kwargs = {"thinking_budget": "invalid", "temperature": 0.5} |
70 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 74 | + result = _process_thinking_config(generation_kwargs) |
71 | 75 | assert result["thinking_config"].thinking_budget == -1 # Dynamic allocation |
72 | 76 | assert result["temperature"] == 0.5 |
73 | 77 |
|
74 | 78 |
|
75 | 79 | def test_process_thinking_level(): |
76 | | - """Test the _process_thinking_config method with different thinking_level values.""" |
| 80 | + """Test the _process_thinking_config function with different thinking_level values.""" |
77 | 81 |
|
78 | 82 | # Test valid thinking_level values |
79 | 83 | generation_kwargs = {"thinking_level": "high", "temperature": 0.7} |
80 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 84 | + result = _process_thinking_config(generation_kwargs) |
81 | 85 |
|
82 | 86 | # thinking_level should be moved to thinking_config |
83 | 87 | assert "thinking_level" not in result |
84 | 88 | assert "thinking_config" in result |
85 | 89 | assert result["thinking_config"].thinking_level == types.ThinkingLevel.HIGH |
| 90 | + assert result["thinking_config"].include_thoughts is True |
86 | 91 | # Other kwargs should be preserved |
87 | 92 | assert result["temperature"] == 0.7 |
88 | 93 |
|
89 | 94 | # Test THINKING_LEVEL_LOW in upper case |
90 | 95 | generation_kwargs = {"thinking_level": "LOW"} |
91 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 96 | + result = _process_thinking_config(generation_kwargs) |
92 | 97 | assert result["thinking_config"].thinking_level == types.ThinkingLevel.LOW |
| 98 | + assert result["thinking_config"].include_thoughts is True |
93 | 99 |
|
94 | | - # Test THINKING_LEVEL_UNSPECIFIED |
| 100 | + # Test MINIMAL (should disable include_thoughts) |
| 101 | + generation_kwargs = {"thinking_level": "MINIMAL"} |
| 102 | + result = _process_thinking_config(generation_kwargs) |
| 103 | + assert result["thinking_config"].thinking_level == types.ThinkingLevel.MINIMAL |
| 104 | + assert result["thinking_config"].include_thoughts is False |
| 105 | + |
| 106 | + # Test THINKING_LEVEL_UNSPECIFIED (invalid value falls back) |
95 | 107 | generation_kwargs = {"thinking_level": "test"} |
96 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 108 | + result = _process_thinking_config(generation_kwargs) |
97 | 109 | assert result["thinking_config"].thinking_level == types.ThinkingLevel.THINKING_LEVEL_UNSPECIFIED |
| 110 | + assert result["thinking_config"].include_thoughts is True |
98 | 111 |
|
99 | 112 | # Test when thinking_level is not present |
100 | 113 | generation_kwargs = {"temperature": 0.5} |
101 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 114 | + result = _process_thinking_config(generation_kwargs) |
102 | 115 | assert result == generation_kwargs # No changes |
103 | 116 |
|
104 | 117 | # Test invalid type (should fall back to THINKING_LEVEL_UNSPECIFIED) |
105 | 118 | generation_kwargs = {"thinking_level": 123, "temperature": 0.5} |
106 | | - result = _process_thinking_config(generation_kwargs.copy()) |
| 119 | + result = _process_thinking_config(generation_kwargs) |
107 | 120 | assert result["thinking_config"].thinking_level == types.ThinkingLevel.THINKING_LEVEL_UNSPECIFIED |
| 121 | + assert result["thinking_config"].include_thoughts is True |
108 | 122 | assert result["temperature"] == 0.5 |
109 | 123 |
|
110 | 124 |
|
| 125 | +def test_process_thinking_config_explicit_include_thoughts(): |
| 126 | + """Test that explicit include_thoughts in generation_kwargs overrides the auto-derived value.""" |
| 127 | + # thinking_budget=0 normally means include_thoughts=False, but user explicitly sets True |
| 128 | + generation_kwargs = {"thinking_budget": 0, "include_thoughts": True} |
| 129 | + result = _process_thinking_config(generation_kwargs) |
| 130 | + assert result["thinking_config"].thinking_budget == 0 |
| 131 | + assert result["thinking_config"].include_thoughts is True |
| 132 | + assert "include_thoughts" not in result # should be popped from top-level kwargs |
| 133 | + |
| 134 | + # thinking_budget=1024 normally means include_thoughts=True, but user explicitly sets False |
| 135 | + generation_kwargs = {"thinking_budget": 1024, "include_thoughts": False} |
| 136 | + result = _process_thinking_config(generation_kwargs) |
| 137 | + assert result["thinking_config"].thinking_budget == 1024 |
| 138 | + assert result["thinking_config"].include_thoughts is False |
| 139 | + assert "include_thoughts" not in result |
| 140 | + |
| 141 | + # thinking_level="high" normally means include_thoughts=True, but user explicitly sets False |
| 142 | + generation_kwargs = {"thinking_level": "high", "include_thoughts": False} |
| 143 | + result = _process_thinking_config(generation_kwargs) |
| 144 | + assert result["thinking_config"].thinking_level == types.ThinkingLevel.HIGH |
| 145 | + assert result["thinking_config"].include_thoughts is False |
| 146 | + assert "include_thoughts" not in result |
| 147 | + |
| 148 | + # thinking_level="minimal" normally means include_thoughts=False, but user explicitly sets True |
| 149 | + generation_kwargs = {"thinking_level": "minimal", "include_thoughts": True} |
| 150 | + result = _process_thinking_config(generation_kwargs) |
| 151 | + assert result["thinking_config"].thinking_level == types.ThinkingLevel.MINIMAL |
| 152 | + assert result["thinking_config"].include_thoughts is True |
| 153 | + assert "include_thoughts" not in result |
| 154 | + |
| 155 | + # include_thoughts alone (no thinking_budget or thinking_level) should just be popped and ignored |
| 156 | + generation_kwargs = {"include_thoughts": True, "temperature": 0.5} |
| 157 | + result = _process_thinking_config(generation_kwargs) |
| 158 | + assert "include_thoughts" not in result |
| 159 | + assert "thinking_config" not in result |
| 160 | + assert result == {"temperature": 0.5} |
| 161 | + |
| 162 | + |
111 | 163 | class TestStreamingChunkConversion: |
112 | 164 | def test_convert_google_chunk_to_streaming_chunk_text_only(self, monkeypatch): |
113 | 165 | monkeypatch.setenv("GOOGLE_API_KEY", "test-api-key") |
@@ -438,7 +490,7 @@ def test_convert_google_chunk_to_streaming_chunk_real_example(self, monkeypatch) |
438 | 490 | assert streaming_chunk.tool_calls[5].index == 5 |
439 | 491 |
|
440 | 492 | def test_aggregate_streaming_chunks_with_reasoning(self): |
441 | | - """Test the _aggregate_streaming_chunks_with_reasoning method for reasoning content aggregation.""" |
| 493 | + """Test the _aggregate_streaming_chunks_with_reasoning function for reasoning content aggregation.""" |
442 | 494 |
|
443 | 495 | # Create mock streaming chunks with reasoning content |
444 | 496 | chunk1 = Mock() |
|
0 commit comments