diff --git a/tests/test_batch.py b/tests/test_batch.py index 76665922f..a78dd0c6b 100644 --- a/tests/test_batch.py +++ b/tests/test_batch.py @@ -467,26 +467,3 @@ async def test_batch_client_passthrough(mock_agenerate): assert call_kwargs["client"] is mock_client -@pytest.mark.asyncio -@patch("think.batch.agenerate", new_callable=AsyncMock) -async def test_batch_cached_content_passthrough(mock_agenerate): - """Test that cached_content is passed through to agenerate.""" - mock_agenerate.return_value = "Response" - - batch = Batch(max_concurrent=5) - req = batch.create( - contents="Test", - context="test.context", - cached_content="my-cached-content", - ) - batch.add(req) - - results = [] - async for completed_req in batch.drain_batch(): - results.append(completed_req) - - assert len(results) == 1 - - # Verify cached_content was passed through - call_kwargs = mock_agenerate.call_args[1] - assert call_kwargs["cached_content"] == "my-cached-content" diff --git a/think/agents.py b/think/agents.py index 6c7608c9f..48126360d 100644 --- a/think/agents.py +++ b/think/agents.py @@ -24,9 +24,6 @@ from datetime import datetime from pathlib import Path from typing import Any, Callable, Optional, TypedDict -from google import genai -from google.genai import types - from think.cluster import cluster, cluster_period, cluster_span from think.muse import ( compose_instructions, @@ -523,7 +520,7 @@ class InputContext: # Prompts prompt: str # Final prompt (with template substitution) system_instruction: str - system_prompt_name: str # For cache key construction + system_prompt_name: str # For diagnostic output (dry-run) # Output output_path: Optional[Path] @@ -1068,50 +1065,9 @@ def scan_day(day: str) -> dict[str, list[str]]: return {"processed": sorted(processed), "repairable": sorted(pending)} -def _get_or_create_cache( - client: genai.Client, - model: str, - display_name: str, - transcript: str, - system_instruction: str, -) -> str | None: - """Return cache name for ``display_name`` or None if content too small. - - Creates cache with ``transcript`` and provided system instruction if needed. - Returns None if content is below estimated 2048 token minimum (~10k chars). - - The cache contains the system instruction + transcript which are identical - for all topics on the same day with the same system prompt, so display_name - should include both day and system prompt name. - """ - MIN_CACHE_CHARS = 10000 # Heuristic: ~4 chars/token → 2048 tokens ≈ 8k-10k chars - - # Check existing caches first - for c in client.caches.list(): - if c.model == model and c.display_name == display_name: - return c.name - - # Skip cache creation for small content - if len(transcript) < MIN_CACHE_CHARS: - return None - - cache = client.caches.create( - model=model, - config=types.CreateCachedContentConfig( - display_name=display_name, - system_instruction=system_instruction, - contents=[transcript], - ttl="1800s", # 30 minutes to accommodate multiple topic analyses - ), - ) - return cache.name - - def generate_agent_output( transcript: str, prompt: str, - api_key: str, - cache_display_name: str | None = None, name: str | None = None, json_output: bool = False, system_instruction: str | None = None, @@ -1124,9 +1080,6 @@ def generate_agent_output( Args: transcript: Clustered transcript content (markdown format). prompt: Agent prompt text. - api_key: Google API key for caching. - cache_display_name: Optional cache key for Google content caching. - Should include system prompt name for proper cache isolation. name: Agent name for token logging context. json_output: If True, request JSON response format. system_instruction: System instruction text. If None, loads default @@ -1139,7 +1092,7 @@ def generate_agent_output( Generated agent output content (markdown or JSON string), or GenerateResult dict if return_result=True. """ - from think.models import generate_with_result, resolve_provider + from think.models import generate_with_result # Use provided system_instruction or fall back to default if system_instruction is None: @@ -1157,46 +1110,15 @@ def generate_agent_output( context = key_to_context(name) if name else "muse.system.unknown" - # Try to use cache if display name provided - # Note: caching is Google-specific, so we check provider first - provider, model = resolve_provider(context) - - client = None - cache_name = None - if cache_display_name and provider == "google": - client = genai.Client( - api_key=api_key, - http_options=types.HttpOptions(retry_options=types.HttpRetryOptions()), - ) - cache_name = _get_or_create_cache( - client, model, cache_display_name, transcript, system_instruction - ) - - if cache_name: - # Cache hit: content already in cache, just send prompt. - # Google-specific params (cached_content, client) are passed via kwargs. - result = generate_with_result( - contents=[prompt], - context=context, - temperature=0.3, - max_output_tokens=max_output_tokens, - thinking_budget=thinking_budget, - model=model, - cached_content=cache_name, - client=client, - json_output=json_output, - ) - else: - # No cache: use unified generate() - result = generate_with_result( - contents=[transcript, prompt], - context=context, - temperature=0.3, - max_output_tokens=max_output_tokens, - thinking_budget=thinking_budget, - system_instruction=system_instruction, - json_output=json_output, - ) + result = generate_with_result( + contents=[transcript, prompt], + context=context, + temperature=0.3, + max_output_tokens=max_output_tokens, + thinking_budget=thinking_budget, + system_instruction=system_instruction, + json_output=json_output, + ) if return_result: return result @@ -1245,7 +1167,6 @@ def _run_generate( transcript = inputs.transcript prompt = inputs.prompt system_instruction = inputs.system_instruction - system_prompt_name = inputs.system_prompt_name output_path = inputs.output_path output_format = inputs.output_format meta = inputs.meta @@ -1256,21 +1177,10 @@ def _run_generate( if output_path: output_exists = output_path.exists() and output_path.stat().st_size > 0 - # Determine cache settings (only for day-based, non-span requests) - cache_display_name = None - if day and not span_mode: - if segment: - cache_display_name = f"{system_prompt_name}_{day}_{segment}" - else: - cache_display_name = f"{system_prompt_name}_{day}" - # Extract generation parameters from metadata meta_thinking_budget = meta.get("thinking_budget") meta_max_output_tokens = meta.get("max_output_tokens") - # Get API key - api_key = os.getenv("GOOGLE_API_KEY", "") - usage_data = None # Dry-run always goes through prompt assembly, regardless of existing output @@ -1336,8 +1246,6 @@ def _run_generate( gen_result = generate_agent_output( transcript, prompt, - api_key, - cache_display_name=cache_display_name, name=name, json_output=is_json_output, system_instruction=system_instruction, diff --git a/think/batch.py b/think/batch.py index 3bfff49af..9202e4fae 100644 --- a/think/batch.py +++ b/think/batch.py @@ -20,7 +20,6 @@ Example: Provider-specific features: - client: Optional client for connection reuse (Google only, others use singletons) - - cached_content: Content caching (Google only) """ import asyncio @@ -54,7 +53,6 @@ class BatchRequest: system_instruction: Optional[str] = None, json_output: bool = False, thinking_budget: Optional[int] = None, - cached_content: Optional[str] = None, timeout_s: Optional[float] = None, ): self.contents = contents @@ -65,7 +63,6 @@ class BatchRequest: self.system_instruction = system_instruction self.json_output = json_output self.thinking_budget = thinking_budget - self.cached_content = cached_content self.timeout_s = timeout_s # Populated after execution @@ -128,7 +125,6 @@ class Batch: system_instruction: Optional[str] = None, json_output: bool = False, thinking_budget: Optional[int] = None, - cached_content: Optional[str] = None, timeout_s: Optional[float] = None, ) -> BatchRequest: """ @@ -160,7 +156,6 @@ class Batch: system_instruction=system_instruction, json_output=json_output, thinking_budget=thinking_budget, - cached_content=cached_content, timeout_s=timeout_s, ) @@ -256,8 +251,6 @@ class Batch: kwargs: dict = {} if self.client is not None: kwargs["client"] = self.client - if request.cached_content is not None: - kwargs["cached_content"] = request.cached_content if request.model is not None: kwargs["model"] = request.model diff --git a/think/providers/google.py b/think/providers/google.py index 8423357d3..1877f216a 100644 --- a/think/providers/google.py +++ b/think/providers/google.py @@ -26,7 +26,7 @@ thinking_budget : int, optional timeout_s : float, optional Request timeout in seconds. **kwargs - Provider-specific options (cached_content, client). + Provider-specific options (client). """ from __future__ import annotations @@ -112,7 +112,6 @@ def _build_generate_config( system_instruction: str | None, json_output: bool, thinking_budget: int | None, - cached_content: str | None, timeout_s: float | None = None, ) -> types.GenerateContentConfig: """Build the GenerateContentConfig. @@ -140,9 +139,6 @@ def _build_generate_config( thinking_budget=thinking_budget ) - if cached_content: - config_args["cached_content"] = cached_content - if timeout_s: # Convert seconds to milliseconds for the SDK timeout_ms = int(timeout_s * 1000) @@ -366,7 +362,6 @@ def run_generate( Returns GenerateResult with text, usage, finish_reason, and thinking. See module docstring for parameter details. """ - cached_content = kwargs.get("cached_content") client = kwargs.get("client") client = get_or_create_client(client) @@ -378,7 +373,6 @@ def run_generate( system_instruction=system_instruction, json_output=json_output, thinking_budget=thinking_budget, - cached_content=cached_content, timeout_s=timeout_s, ) @@ -412,7 +406,6 @@ async def run_agenerate( Returns GenerateResult with text, usage, finish_reason, and thinking. See module docstring for parameter details. """ - cached_content = kwargs.get("cached_content") client = kwargs.get("client") client = get_or_create_client(client) @@ -424,7 +417,6 @@ async def run_agenerate( system_instruction=system_instruction, json_output=json_output, thinking_budget=thinking_budget, - cached_content=cached_content, timeout_s=timeout_s, )