| @@ -165,6 +165,54 @@ func TestEnsureCacheControl(t *testing.T) { · 164 unmodified lines |
| 165 | 165 | t.Errorf("system should have cache_control even with empty tools array") |
| 166 | 166 | } |
| 167 | 167 | }) |
| 168 | + |
| 169 | + // Test case 8: Messages caching for multi-turn (second-to-last user) |
| 170 | + t.Run("Messages Caching Second-To-Last User", func(t *testing.T) { |
| 171 | + input := []byte(`{ |
| 172 | + "model": "claude-3-5-sonnet", |
| 173 | + "messages": [ |
| 174 | + {"role": "user", "content": "First user"}, |
| 175 | + {"role": "assistant", "content": "Assistant reply"}, |
| 176 | + {"role": "user", "content": "Second user"}, |
| 177 | + {"role": "assistant", "content": "Assistant reply 2"}, |
| 178 | + {"role": "user", "content": "Third user"} |
| 179 | + ] |
| 180 | + }`) |
| 181 | + output := ensureCacheControl(input) |
| 182 | + |
| 183 | + cacheType := gjson.GetBytes(output, "messages.2.content.0.cache_control.type") |
| 184 | + if cacheType.String() != "ephemeral" { |
| 185 | + t.Errorf("cache_control not found on second-to-last user turn. Output: %s", string(output)) |
| 186 | + } |
| 187 | + |
| 188 | + lastUserCache := gjson.GetBytes(output, "messages.4.content.0.cache_control") |
| 189 | + if lastUserCache.Exists() { |
| 190 | + t.Errorf("last user turn should NOT have cache_control") |
| 191 | + } |
| 192 | + }) |
| 193 | + |
| 194 | + // Test case 9: Existing message cache_control should skip injection |
| 195 | + t.Run("Messages Skip When Cache Control Exists", func(t *testing.T) { |
| 196 | + input := []byte(`{ |
| 197 | + "model": "claude-3-5-sonnet", |
| 198 | + "messages": [ |
| 199 | + {"role": "user", "content": [{"type": "text", "text": "First user"}]}, |
| 200 | + {"role": "assistant", "content": [{"type": "text", "text": "Assistant reply", "cache_control": {"type": "ephemeral"}}]}, |
| 201 | + {"role": "user", "content": [{"type": "text", "text": "Second user"}]} |
| 202 | + ] |
| 203 | + }`) |
| 204 | + output := ensureCacheControl(input) |
| 205 | + |
| 206 | + userCache := gjson.GetBytes(output, "messages.0.content.0.cache_control") |
| 207 | + if userCache.Exists() { |
| 208 | + t.Errorf("cache_control should NOT be injected when a message already has cache_control") |
| 209 | + } |
| 210 | + |
| 211 | + existingCache := gjson.GetBytes(output, "messages.1.content.0.cache_control.type") |
| 212 | + if existingCache.String() != "ephemeral" { |
| 213 | + t.Errorf("existing cache_control should be preserved. Output: %s", string(output)) |
| 214 | + } |
| 215 | + }) |
| 168 | 216 | } |
| 169 | 217 | |
| 170 | 218 | // TestCacheControlOrder verifies the correct order: tools -> system -> messages |