Use the new Gemini 2.5 Flash
Updated to support Thinking Tokens as a ratio of the max allowed Updated tests Updated README
This commit is contained in:
@@ -390,7 +390,7 @@ Use zen and perform a thorough precommit ensuring there aren't any new regressio
|
|||||||
- Supports specialized analysis types: architecture, performance, security, quality
|
- Supports specialized analysis types: architecture, performance, security, quality
|
||||||
- Uses file paths (not content) for clean terminal output
|
- Uses file paths (not content) for clean terminal output
|
||||||
- Can identify patterns, anti-patterns, and refactoring opportunities
|
- Can identify patterns, anti-patterns, and refactoring opportunities
|
||||||
- **Web search capability**: When enabled with `use_websearch`, the model can request Claude to perform web searches and share results back to enhance analysis with current documentation, design patterns, and best practices
|
- **Web search capability**: When enabled with `use_websearch` (default: true), the model can request Claude to perform web searches and share results back to enhance analysis with current documentation, design patterns, and best practices
|
||||||
### 7. `get_version` - Server Information
|
### 7. `get_version` - Server Information
|
||||||
```
|
```
|
||||||
"Get zen to show its version"
|
"Get zen to show its version"
|
||||||
|
|||||||
12
config.py
12
config.py
@@ -26,7 +26,15 @@ DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "auto")
|
|||||||
|
|
||||||
# Validate DEFAULT_MODEL and set to "auto" if invalid
|
# Validate DEFAULT_MODEL and set to "auto" if invalid
|
||||||
# Only include actually supported models from providers
|
# Only include actually supported models from providers
|
||||||
VALID_MODELS = ["auto", "flash", "pro", "o3", "o3-mini", "gemini-2.0-flash", "gemini-2.5-pro-preview-06-05"]
|
VALID_MODELS = [
|
||||||
|
"auto",
|
||||||
|
"flash",
|
||||||
|
"pro",
|
||||||
|
"o3",
|
||||||
|
"o3-mini",
|
||||||
|
"gemini-2.5-flash-preview-05-20",
|
||||||
|
"gemini-2.5-pro-preview-06-05",
|
||||||
|
]
|
||||||
if DEFAULT_MODEL not in VALID_MODELS:
|
if DEFAULT_MODEL not in VALID_MODELS:
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -47,7 +55,7 @@ MODEL_CAPABILITIES_DESC = {
|
|||||||
"o3": "Strong reasoning (200K context) - Logical problems, code generation, systematic analysis",
|
"o3": "Strong reasoning (200K context) - Logical problems, code generation, systematic analysis",
|
||||||
"o3-mini": "Fast O3 variant (200K context) - Balanced performance/speed, moderate complexity",
|
"o3-mini": "Fast O3 variant (200K context) - Balanced performance/speed, moderate complexity",
|
||||||
# Full model names also supported
|
# Full model names also supported
|
||||||
"gemini-2.0-flash": "Ultra-fast (1M context) - Quick analysis, simple queries, rapid iterations",
|
"gemini-2.5-flash-preview-05-20": "Ultra-fast (1M context) - Quick analysis, simple queries, rapid iterations",
|
||||||
"gemini-2.5-pro-preview-06-05": "Deep reasoning + thinking mode (1M context) - Complex problems, architecture, deep analysis",
|
"gemini-2.5-pro-preview-06-05": "Deep reasoning + thinking mode (1M context) - Complex problems, architecture, deep analysis",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,26 +13,29 @@ class GeminiModelProvider(ModelProvider):
|
|||||||
|
|
||||||
# Model configurations
|
# Model configurations
|
||||||
SUPPORTED_MODELS = {
|
SUPPORTED_MODELS = {
|
||||||
"gemini-2.0-flash": {
|
"gemini-2.5-flash-preview-05-20": {
|
||||||
"max_tokens": 1_048_576, # 1M tokens
|
"max_tokens": 1_048_576, # 1M tokens
|
||||||
"supports_extended_thinking": False,
|
"supports_extended_thinking": True,
|
||||||
|
"max_thinking_tokens": 24576, # Flash 2.5 thinking budget limit
|
||||||
},
|
},
|
||||||
"gemini-2.5-pro-preview-06-05": {
|
"gemini-2.5-pro-preview-06-05": {
|
||||||
"max_tokens": 1_048_576, # 1M tokens
|
"max_tokens": 1_048_576, # 1M tokens
|
||||||
"supports_extended_thinking": True,
|
"supports_extended_thinking": True,
|
||||||
|
"max_thinking_tokens": 32768, # Pro 2.5 thinking budget limit
|
||||||
},
|
},
|
||||||
# Shorthands
|
# Shorthands
|
||||||
"flash": "gemini-2.0-flash",
|
"flash": "gemini-2.5-flash-preview-05-20",
|
||||||
"pro": "gemini-2.5-pro-preview-06-05",
|
"pro": "gemini-2.5-pro-preview-06-05",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Thinking mode configurations for models that support it
|
# Thinking mode configurations - percentages of model's max_thinking_tokens
|
||||||
|
# These percentages work across all models that support thinking
|
||||||
THINKING_BUDGETS = {
|
THINKING_BUDGETS = {
|
||||||
"minimal": 128, # Minimum for 2.5 Pro - fast responses
|
"minimal": 0.005, # 0.5% of max - minimal thinking for fast responses
|
||||||
"low": 2048, # Light reasoning tasks
|
"low": 0.08, # 8% of max - light reasoning tasks
|
||||||
"medium": 8192, # Balanced reasoning (default)
|
"medium": 0.33, # 33% of max - balanced reasoning (default)
|
||||||
"high": 16384, # Complex analysis
|
"high": 0.67, # 67% of max - complex analysis
|
||||||
"max": 32768, # Maximum reasoning depth
|
"max": 1.0, # 100% of max - full thinking budget
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, api_key: str, **kwargs):
|
def __init__(self, api_key: str, **kwargs):
|
||||||
@@ -107,9 +110,12 @@ class GeminiModelProvider(ModelProvider):
|
|||||||
# Add thinking configuration for models that support it
|
# Add thinking configuration for models that support it
|
||||||
capabilities = self.get_capabilities(resolved_name)
|
capabilities = self.get_capabilities(resolved_name)
|
||||||
if capabilities.supports_extended_thinking and thinking_mode in self.THINKING_BUDGETS:
|
if capabilities.supports_extended_thinking and thinking_mode in self.THINKING_BUDGETS:
|
||||||
generation_config.thinking_config = types.ThinkingConfig(
|
# Get model's max thinking tokens and calculate actual budget
|
||||||
thinking_budget=self.THINKING_BUDGETS[thinking_mode]
|
model_config = self.SUPPORTED_MODELS.get(resolved_name)
|
||||||
)
|
if model_config and "max_thinking_tokens" in model_config:
|
||||||
|
max_thinking_tokens = model_config["max_thinking_tokens"]
|
||||||
|
actual_thinking_budget = int(max_thinking_tokens * self.THINKING_BUDGETS[thinking_mode])
|
||||||
|
generation_config.thinking_config = types.ThinkingConfig(thinking_budget=actual_thinking_budget)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Generate content
|
# Generate content
|
||||||
@@ -164,6 +170,23 @@ class GeminiModelProvider(ModelProvider):
|
|||||||
capabilities = self.get_capabilities(model_name)
|
capabilities = self.get_capabilities(model_name)
|
||||||
return capabilities.supports_extended_thinking
|
return capabilities.supports_extended_thinking
|
||||||
|
|
||||||
|
def get_thinking_budget(self, model_name: str, thinking_mode: str) -> int:
|
||||||
|
"""Get actual thinking token budget for a model and thinking mode."""
|
||||||
|
resolved_name = self._resolve_model_name(model_name)
|
||||||
|
model_config = self.SUPPORTED_MODELS.get(resolved_name, {})
|
||||||
|
|
||||||
|
if not model_config.get("supports_extended_thinking", False):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if thinking_mode not in self.THINKING_BUDGETS:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
max_thinking_tokens = model_config.get("max_thinking_tokens", 0)
|
||||||
|
if max_thinking_tokens == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return int(max_thinking_tokens * self.THINKING_BUDGETS[thinking_mode])
|
||||||
|
|
||||||
def _resolve_model_name(self, model_name: str) -> str:
|
def _resolve_model_name(self, model_name: str) -> str:
|
||||||
"""Resolve model shorthand to full name."""
|
"""Resolve model shorthand to full name."""
|
||||||
# Check if it's a shorthand
|
# Check if it's a shorthand
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class ModelProviderRegistry:
|
|||||||
"""Get provider instance for a specific model name.
|
"""Get provider instance for a specific model name.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
model_name: Name of the model (e.g., "gemini-2.0-flash", "o3-mini")
|
model_name: Name of the model (e.g., "gemini-2.5-flash-preview-05-20", "o3-mini")
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ModelProvider instance that supports this model
|
ModelProvider instance that supports this model
|
||||||
@@ -137,7 +137,7 @@ class ModelProviderRegistry:
|
|||||||
2. Gemini 2.0 Flash (fast and efficient) if Gemini API key available
|
2. Gemini 2.0 Flash (fast and efficient) if Gemini API key available
|
||||||
3. OpenAI o3 (high performance) if OpenAI API key available
|
3. OpenAI o3 (high performance) if OpenAI API key available
|
||||||
4. Gemini 2.5 Pro (deep reasoning) if Gemini API key available
|
4. Gemini 2.5 Pro (deep reasoning) if Gemini API key available
|
||||||
5. Fallback to gemini-2.0-flash (most common case)
|
5. Fallback to gemini-2.5-flash-preview-05-20 (most common case)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Model name string for fallback use
|
Model name string for fallback use
|
||||||
@@ -150,11 +150,11 @@ class ModelProviderRegistry:
|
|||||||
if openai_available:
|
if openai_available:
|
||||||
return "o3-mini" # Balanced performance/cost
|
return "o3-mini" # Balanced performance/cost
|
||||||
elif gemini_available:
|
elif gemini_available:
|
||||||
return "gemini-2.0-flash" # Fast and efficient
|
return "gemini-2.5-flash-preview-05-20" # Fast and efficient
|
||||||
else:
|
else:
|
||||||
# No API keys available - return a reasonable default
|
# No API keys available - return a reasonable default
|
||||||
# This maintains backward compatibility for tests
|
# This maintains backward compatibility for tests
|
||||||
return "gemini-2.0-flash"
|
return "gemini-2.5-flash-preview-05-20"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_available_providers_with_keys(cls) -> list[ProviderType]:
|
def get_available_providers_with_keys(cls) -> list[ProviderType]:
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class TestModelThinkingConfig(BaseSimulatorTest):
|
|||||||
"chat",
|
"chat",
|
||||||
{
|
{
|
||||||
"prompt": "What is 3 + 3? Give a quick answer.",
|
"prompt": "What is 3 + 3? Give a quick answer.",
|
||||||
"model": "flash", # Should resolve to gemini-2.0-flash
|
"model": "flash", # Should resolve to gemini-2.5-flash-preview-05-20
|
||||||
"thinking_mode": "high", # Should be ignored for Flash model
|
"thinking_mode": "high", # Should be ignored for Flash model
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -80,7 +80,7 @@ class TestModelThinkingConfig(BaseSimulatorTest):
|
|||||||
("pro", "should work with Pro model"),
|
("pro", "should work with Pro model"),
|
||||||
("flash", "should work with Flash model"),
|
("flash", "should work with Flash model"),
|
||||||
("gemini-2.5-pro-preview-06-05", "should work with full Pro model name"),
|
("gemini-2.5-pro-preview-06-05", "should work with full Pro model name"),
|
||||||
("gemini-2.0-flash", "should work with full Flash model name"),
|
("gemini-2.5-flash-preview-05-20", "should work with full Flash model name"),
|
||||||
]
|
]
|
||||||
|
|
||||||
success_count = 0
|
success_count = 0
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ if "OPENAI_API_KEY" not in os.environ:
|
|||||||
|
|
||||||
# Set default model to a specific value for tests to avoid auto mode
|
# Set default model to a specific value for tests to avoid auto mode
|
||||||
# This prevents all tests from failing due to missing model parameter
|
# This prevents all tests from failing due to missing model parameter
|
||||||
os.environ["DEFAULT_MODEL"] = "gemini-2.0-flash"
|
os.environ["DEFAULT_MODEL"] = "gemini-2.5-flash-preview-05-20"
|
||||||
|
|
||||||
# Force reload of config module to pick up the env var
|
# Force reload of config module to pick up the env var
|
||||||
import config # noqa: E402
|
import config # noqa: E402
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from unittest.mock import Mock
|
|||||||
from providers.base import ModelCapabilities, ProviderType, RangeTemperatureConstraint
|
from providers.base import ModelCapabilities, ProviderType, RangeTemperatureConstraint
|
||||||
|
|
||||||
|
|
||||||
def create_mock_provider(model_name="gemini-2.0-flash", max_tokens=1_048_576):
|
def create_mock_provider(model_name="gemini-2.5-flash-preview-05-20", max_tokens=1_048_576):
|
||||||
"""Create a properly configured mock provider."""
|
"""Create a properly configured mock provider."""
|
||||||
mock_provider = Mock()
|
mock_provider = Mock()
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class TestClaudeContinuationOffers:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Analysis complete.",
|
content="Analysis complete.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -129,7 +129,7 @@ class TestClaudeContinuationOffers:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Continued analysis.",
|
content="Continued analysis.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -162,7 +162,7 @@ class TestClaudeContinuationOffers:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Analysis complete. The code looks good.",
|
content="Analysis complete. The code looks good.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -208,7 +208,7 @@ I'd be happy to examine the error handling patterns in more detail if that would
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=content_with_followup,
|
content=content_with_followup,
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -253,7 +253,7 @@ I'd be happy to examine the error handling patterns in more detail if that would
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Continued analysis complete.",
|
content="Continued analysis complete.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -309,7 +309,7 @@ I'd be happy to examine the error handling patterns in more detail if that would
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Final response.",
|
content="Final response.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -358,7 +358,7 @@ class TestContinuationIntegration:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Analysis result",
|
content="Analysis result",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -411,7 +411,7 @@ class TestContinuationIntegration:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Structure analysis done.",
|
content="Structure analysis done.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -448,7 +448,7 @@ class TestContinuationIntegration:
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Performance analysis done.",
|
content="Performance analysis done.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class TestDynamicContextRequests:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=clarification_json, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=clarification_json, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class TestDynamicContextRequests:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=normal_response, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=normal_response, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ class TestDynamicContextRequests:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=malformed_json, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=malformed_json, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class TestDynamicContextRequests:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=clarification_json, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=clarification_json, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ class TestCollaborationWorkflow:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=clarification_json, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=clarification_json, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ class TestCollaborationWorkflow:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=clarification_json, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=clarification_json, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ class TestCollaborationWorkflow:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=final_response, usage={}, model_name="gemini-2.0-flash", metadata={}
|
content=final_response, usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
|
|
||||||
result2 = await tool.execute(
|
result2 = await tool.execute(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class TestConfig:
|
|||||||
def test_model_config(self):
|
def test_model_config(self):
|
||||||
"""Test model configuration"""
|
"""Test model configuration"""
|
||||||
# DEFAULT_MODEL is set in conftest.py for tests
|
# DEFAULT_MODEL is set in conftest.py for tests
|
||||||
assert DEFAULT_MODEL == "gemini-2.0-flash"
|
assert DEFAULT_MODEL == "gemini-2.5-flash-preview-05-20"
|
||||||
assert MAX_CONTEXT_TOKENS == 1_000_000
|
assert MAX_CONTEXT_TOKENS == 1_000_000
|
||||||
|
|
||||||
def test_temperature_defaults(self):
|
def test_temperature_defaults(self):
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ async def test_conversation_history_field_mapping():
|
|||||||
mock_provider = MagicMock()
|
mock_provider = MagicMock()
|
||||||
mock_provider.get_capabilities.return_value = ModelCapabilities(
|
mock_provider.get_capabilities.return_value = ModelCapabilities(
|
||||||
provider=ProviderType.GOOGLE,
|
provider=ProviderType.GOOGLE,
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
friendly_name="Gemini",
|
friendly_name="Gemini",
|
||||||
max_tokens=200000,
|
max_tokens=200000,
|
||||||
supports_extended_thinking=True,
|
supports_extended_thinking=True,
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class TestConversationHistoryBugFix:
|
|||||||
return Mock(
|
return Mock(
|
||||||
content="Response with conversation context",
|
content="Response with conversation context",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ class TestConversationHistoryBugFix:
|
|||||||
return Mock(
|
return Mock(
|
||||||
content="Response without history",
|
content="Response without history",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ class TestConversationHistoryBugFix:
|
|||||||
return Mock(
|
return Mock(
|
||||||
content="New conversation response",
|
content="New conversation response",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ class TestConversationHistoryBugFix:
|
|||||||
return Mock(
|
return Mock(
|
||||||
content="Analysis of new files complete",
|
content="Analysis of new files complete",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ I'd be happy to review these security findings in detail if that would be helpfu
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content=content,
|
content=content,
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -159,7 +159,7 @@ I'd be happy to review these security findings in detail if that would be helpfu
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Critical security vulnerability confirmed. The authentication function always returns true, bypassing all security checks.",
|
content="Critical security vulnerability confirmed. The authentication function always returns true, bypassing all security checks.",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -284,7 +284,7 @@ I'd be happy to review these security findings in detail if that would be helpfu
|
|||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Security review of auth.py shows vulnerabilities",
|
content="Security review of auth.py shows vulnerabilities",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ class TestIntelligentFallback:
|
|||||||
|
|
||||||
@patch.dict(os.environ, {"OPENAI_API_KEY": "", "GEMINI_API_KEY": "test-gemini-key"}, clear=False)
|
@patch.dict(os.environ, {"OPENAI_API_KEY": "", "GEMINI_API_KEY": "test-gemini-key"}, clear=False)
|
||||||
def test_prefers_gemini_flash_when_openai_unavailable(self):
|
def test_prefers_gemini_flash_when_openai_unavailable(self):
|
||||||
"""Test that gemini-2.0-flash is used when only Gemini API key is available"""
|
"""Test that gemini-2.5-flash-preview-05-20 is used when only Gemini API key is available"""
|
||||||
ModelProviderRegistry.clear_cache()
|
ModelProviderRegistry.clear_cache()
|
||||||
fallback_model = ModelProviderRegistry.get_preferred_fallback_model()
|
fallback_model = ModelProviderRegistry.get_preferred_fallback_model()
|
||||||
assert fallback_model == "gemini-2.0-flash"
|
assert fallback_model == "gemini-2.5-flash-preview-05-20"
|
||||||
|
|
||||||
@patch.dict(os.environ, {"OPENAI_API_KEY": "sk-test-key", "GEMINI_API_KEY": "test-gemini-key"}, clear=False)
|
@patch.dict(os.environ, {"OPENAI_API_KEY": "sk-test-key", "GEMINI_API_KEY": "test-gemini-key"}, clear=False)
|
||||||
def test_prefers_openai_when_both_available(self):
|
def test_prefers_openai_when_both_available(self):
|
||||||
@@ -50,7 +50,7 @@ class TestIntelligentFallback:
|
|||||||
"""Test fallback behavior when no API keys are available"""
|
"""Test fallback behavior when no API keys are available"""
|
||||||
ModelProviderRegistry.clear_cache()
|
ModelProviderRegistry.clear_cache()
|
||||||
fallback_model = ModelProviderRegistry.get_preferred_fallback_model()
|
fallback_model = ModelProviderRegistry.get_preferred_fallback_model()
|
||||||
assert fallback_model == "gemini-2.0-flash" # Default fallback
|
assert fallback_model == "gemini-2.5-flash-preview-05-20" # Default fallback
|
||||||
|
|
||||||
def test_available_providers_with_keys(self):
|
def test_available_providers_with_keys(self):
|
||||||
"""Test the get_available_providers_with_keys method"""
|
"""Test the get_available_providers_with_keys method"""
|
||||||
@@ -140,8 +140,8 @@ class TestIntelligentFallback:
|
|||||||
|
|
||||||
history, tokens = build_conversation_history(context, model_context=None)
|
history, tokens = build_conversation_history(context, model_context=None)
|
||||||
|
|
||||||
# Should use gemini-2.0-flash when only Gemini is available
|
# Should use gemini-2.5-flash-preview-05-20 when only Gemini is available
|
||||||
mock_context_class.assert_called_once_with("gemini-2.0-flash")
|
mock_context_class.assert_called_once_with("gemini-2.5-flash-preview-05-20")
|
||||||
|
|
||||||
def test_non_auto_mode_unchanged(self):
|
def test_non_auto_mode_unchanged(self):
|
||||||
"""Test that non-auto mode behavior is unchanged"""
|
"""Test that non-auto mode behavior is unchanged"""
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="This is a test response",
|
content="This is a test response",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -100,7 +100,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="Processed large prompt",
|
content="Processed large prompt",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -212,7 +212,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="Success",
|
content="Success",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -245,7 +245,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="Success",
|
content="Success",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -276,7 +276,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="Success",
|
content="Success",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
@@ -298,7 +298,7 @@ class TestLargePromptHandling:
|
|||||||
mock_provider.generate_content.return_value = MagicMock(
|
mock_provider.generate_content.return_value = MagicMock(
|
||||||
content="Success",
|
content="Success",
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class TestPromptRegression:
|
|||||||
return Mock(
|
return Mock(
|
||||||
content=text,
|
content=text,
|
||||||
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
usage={"input_tokens": 10, "output_tokens": 20, "total_tokens": 30},
|
||||||
model_name="gemini-2.0-flash",
|
model_name="gemini-2.5-flash-preview-05-20",
|
||||||
metadata={"finish_reason": "STOP"},
|
metadata={"finish_reason": "STOP"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class TestModelProviderRegistry:
|
|||||||
"""Test getting provider for a specific model"""
|
"""Test getting provider for a specific model"""
|
||||||
ModelProviderRegistry.register_provider(ProviderType.GOOGLE, GeminiModelProvider)
|
ModelProviderRegistry.register_provider(ProviderType.GOOGLE, GeminiModelProvider)
|
||||||
|
|
||||||
provider = ModelProviderRegistry.get_provider_for_model("gemini-2.0-flash")
|
provider = ModelProviderRegistry.get_provider_for_model("gemini-2.5-flash-preview-05-20")
|
||||||
|
|
||||||
assert provider is not None
|
assert provider is not None
|
||||||
assert isinstance(provider, GeminiModelProvider)
|
assert isinstance(provider, GeminiModelProvider)
|
||||||
@@ -80,10 +80,10 @@ class TestGeminiProvider:
|
|||||||
"""Test getting model capabilities"""
|
"""Test getting model capabilities"""
|
||||||
provider = GeminiModelProvider(api_key="test-key")
|
provider = GeminiModelProvider(api_key="test-key")
|
||||||
|
|
||||||
capabilities = provider.get_capabilities("gemini-2.0-flash")
|
capabilities = provider.get_capabilities("gemini-2.5-flash-preview-05-20")
|
||||||
|
|
||||||
assert capabilities.provider == ProviderType.GOOGLE
|
assert capabilities.provider == ProviderType.GOOGLE
|
||||||
assert capabilities.model_name == "gemini-2.0-flash"
|
assert capabilities.model_name == "gemini-2.5-flash-preview-05-20"
|
||||||
assert capabilities.max_tokens == 1_048_576
|
assert capabilities.max_tokens == 1_048_576
|
||||||
assert not capabilities.supports_extended_thinking
|
assert not capabilities.supports_extended_thinking
|
||||||
|
|
||||||
@@ -103,13 +103,13 @@ class TestGeminiProvider:
|
|||||||
assert provider.validate_model_name("pro")
|
assert provider.validate_model_name("pro")
|
||||||
|
|
||||||
capabilities = provider.get_capabilities("flash")
|
capabilities = provider.get_capabilities("flash")
|
||||||
assert capabilities.model_name == "gemini-2.0-flash"
|
assert capabilities.model_name == "gemini-2.5-flash-preview-05-20"
|
||||||
|
|
||||||
def test_supports_thinking_mode(self):
|
def test_supports_thinking_mode(self):
|
||||||
"""Test thinking mode support detection"""
|
"""Test thinking mode support detection"""
|
||||||
provider = GeminiModelProvider(api_key="test-key")
|
provider = GeminiModelProvider(api_key="test-key")
|
||||||
|
|
||||||
assert not provider.supports_thinking_mode("gemini-2.0-flash")
|
assert provider.supports_thinking_mode("gemini-2.5-flash-preview-05-20")
|
||||||
assert provider.supports_thinking_mode("gemini-2.5-pro-preview-06-05")
|
assert provider.supports_thinking_mode("gemini-2.5-pro-preview-06-05")
|
||||||
|
|
||||||
@patch("google.genai.Client")
|
@patch("google.genai.Client")
|
||||||
@@ -133,11 +133,13 @@ class TestGeminiProvider:
|
|||||||
|
|
||||||
provider = GeminiModelProvider(api_key="test-key")
|
provider = GeminiModelProvider(api_key="test-key")
|
||||||
|
|
||||||
response = provider.generate_content(prompt="Test prompt", model_name="gemini-2.0-flash", temperature=0.7)
|
response = provider.generate_content(
|
||||||
|
prompt="Test prompt", model_name="gemini-2.5-flash-preview-05-20", temperature=0.7
|
||||||
|
)
|
||||||
|
|
||||||
assert isinstance(response, ModelResponse)
|
assert isinstance(response, ModelResponse)
|
||||||
assert response.content == "Generated content"
|
assert response.content == "Generated content"
|
||||||
assert response.model_name == "gemini-2.0-flash"
|
assert response.model_name == "gemini-2.5-flash-preview-05-20"
|
||||||
assert response.provider == ProviderType.GOOGLE
|
assert response.provider == ProviderType.GOOGLE
|
||||||
assert response.usage["input_tokens"] == 10
|
assert response.usage["input_tokens"] == 10
|
||||||
assert response.usage["output_tokens"] == 20
|
assert response.usage["output_tokens"] == 20
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class TestServerTools:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Chat response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Chat response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class TestThinkingModes:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Minimal thinking response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Minimal thinking response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class TestThinkingModes:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Low thinking response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Low thinking response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ class TestThinkingModes:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Medium thinking response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Medium thinking response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ class TestThinkingModes:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="High thinking response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="High thinking response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ class TestThinkingModes:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Max thinking response", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Max thinking response", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -222,18 +222,22 @@ class TestThinkingModes:
|
|||||||
async def prepare_prompt(self, request):
|
async def prepare_prompt(self, request):
|
||||||
return "test"
|
return "test"
|
||||||
|
|
||||||
# Expected mappings
|
# Test dynamic budget calculation for Flash 2.5
|
||||||
|
from providers.gemini import GeminiModelProvider
|
||||||
|
|
||||||
|
provider = GeminiModelProvider(api_key="test-key")
|
||||||
|
flash_model = "gemini-2.5-flash-preview-05-20"
|
||||||
|
flash_max_tokens = 24576
|
||||||
|
|
||||||
expected_budgets = {
|
expected_budgets = {
|
||||||
"minimal": 128,
|
"minimal": int(flash_max_tokens * 0.005), # 123
|
||||||
"low": 2048,
|
"low": int(flash_max_tokens * 0.08), # 1966
|
||||||
"medium": 8192,
|
"medium": int(flash_max_tokens * 0.33), # 8110
|
||||||
"high": 16384,
|
"high": int(flash_max_tokens * 0.67), # 16465
|
||||||
"max": 32768,
|
"max": int(flash_max_tokens * 1.0), # 24576
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check each mode in create_model
|
# Check each mode using the helper method
|
||||||
for _mode, _expected_budget in expected_budgets.items():
|
for mode, expected_budget in expected_budgets.items():
|
||||||
# The budget mapping is inside create_model
|
actual_budget = provider.get_thinking_budget(flash_model, mode)
|
||||||
# We can't easily test it without calling the method
|
assert actual_budget == expected_budget, f"Mode {mode}: expected {expected_budget}, got {actual_budget}"
|
||||||
# But we've verified the values are correct in the code
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class TestThinkDeepTool:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = True
|
mock_provider.supports_thinking_mode.return_value = True
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Extended analysis", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Extended analysis", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ class TestCodeReviewTool:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Security issues found", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Security issues found", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ class TestDebugIssueTool:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Root cause: race condition", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Root cause: race condition", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ class TestAnalyzeTool:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Architecture analysis", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Architecture analysis", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ class TestAbsolutePathValidation:
|
|||||||
mock_provider.get_provider_type.return_value = Mock(value="google")
|
mock_provider.get_provider_type.return_value = Mock(value="google")
|
||||||
mock_provider.supports_thinking_mode.return_value = False
|
mock_provider.supports_thinking_mode.return_value = False
|
||||||
mock_provider.generate_content.return_value = Mock(
|
mock_provider.generate_content.return_value = Mock(
|
||||||
content="Analysis complete", usage={}, model_name="gemini-2.0-flash", metadata={}
|
content="Analysis complete", usage={}, model_name="gemini-2.5-flash-preview-05-20", metadata={}
|
||||||
)
|
)
|
||||||
mock_get_provider.return_value = mock_provider
|
mock_get_provider.return_value = mock_provider
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class AnalyzeTool(BaseTool):
|
|||||||
"thinking_mode": {
|
"thinking_mode": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["minimal", "low", "medium", "high", "max"],
|
"enum": ["minimal", "low", "medium", "high", "max"],
|
||||||
"description": "Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768)",
|
"description": "Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max)",
|
||||||
},
|
},
|
||||||
"use_websearch": {
|
"use_websearch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class ToolRequest(BaseModel):
|
|||||||
# Higher values allow for more complex reasoning but increase latency and cost
|
# Higher values allow for more complex reasoning but increase latency and cost
|
||||||
thinking_mode: Optional[Literal["minimal", "low", "medium", "high", "max"]] = Field(
|
thinking_mode: Optional[Literal["minimal", "low", "medium", "high", "max"]] = Field(
|
||||||
None,
|
None,
|
||||||
description="Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768)",
|
description="Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max)",
|
||||||
)
|
)
|
||||||
use_websearch: Optional[bool] = Field(
|
use_websearch: Optional[bool] = Field(
|
||||||
True,
|
True,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class ChatTool(BaseTool):
|
|||||||
"thinking_mode": {
|
"thinking_mode": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["minimal", "low", "medium", "high", "max"],
|
"enum": ["minimal", "low", "medium", "high", "max"],
|
||||||
"description": "Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768)",
|
"description": "Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max)",
|
||||||
},
|
},
|
||||||
"use_websearch": {
|
"use_websearch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class CodeReviewTool(BaseTool):
|
|||||||
"thinking_mode": {
|
"thinking_mode": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["minimal", "low", "medium", "high", "max"],
|
"enum": ["minimal", "low", "medium", "high", "max"],
|
||||||
"description": "Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768)",
|
"description": "Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max)",
|
||||||
},
|
},
|
||||||
"use_websearch": {
|
"use_websearch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class DebugIssueTool(BaseTool):
|
|||||||
"thinking_mode": {
|
"thinking_mode": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["minimal", "low", "medium", "high", "max"],
|
"enum": ["minimal", "low", "medium", "high", "max"],
|
||||||
"description": "Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768)",
|
"description": "Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max)",
|
||||||
},
|
},
|
||||||
"use_websearch": {
|
"use_websearch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class ThinkDeepTool(BaseTool):
|
|||||||
"thinking_mode": {
|
"thinking_mode": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["minimal", "low", "medium", "high", "max"],
|
"enum": ["minimal", "low", "medium", "high", "max"],
|
||||||
"description": f"Thinking depth: minimal (128), low (2048), medium (8192), high (16384), max (32768). Defaults to '{self.get_default_thinking_mode()}' if not specified.",
|
"description": f"Thinking depth: minimal (0.5% of model max), low (8%), medium (33%), high (67%), max (100% of model max). Defaults to '{self.get_default_thinking_mode()}' if not specified.",
|
||||||
},
|
},
|
||||||
"use_websearch": {
|
"use_websearch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class ConversationTurn(BaseModel):
|
|||||||
files: List of file paths referenced in this specific turn
|
files: List of file paths referenced in this specific turn
|
||||||
tool_name: Which tool generated this turn (for cross-tool tracking)
|
tool_name: Which tool generated this turn (for cross-tool tracking)
|
||||||
model_provider: Provider used (e.g., "google", "openai")
|
model_provider: Provider used (e.g., "google", "openai")
|
||||||
model_name: Specific model used (e.g., "gemini-2.0-flash", "o3-mini")
|
model_name: Specific model used (e.g., "gemini-2.5-flash-preview-05-20", "o3-mini")
|
||||||
model_metadata: Additional model-specific metadata (e.g., thinking mode, token usage)
|
model_metadata: Additional model-specific metadata (e.g., thinking mode, token usage)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ def add_turn(
|
|||||||
files: Optional list of files referenced in this turn
|
files: Optional list of files referenced in this turn
|
||||||
tool_name: Name of the tool adding this turn (for attribution)
|
tool_name: Name of the tool adding this turn (for attribution)
|
||||||
model_provider: Provider used (e.g., "google", "openai")
|
model_provider: Provider used (e.g., "google", "openai")
|
||||||
model_name: Specific model used (e.g., "gemini-2.0-flash", "o3-mini")
|
model_name: Specific model used (e.g., "gemini-2.5-flash-preview-05-20", "o3-mini")
|
||||||
model_metadata: Additional model info (e.g., thinking mode, token usage)
|
model_metadata: Additional model info (e.g., thinking mode, token usage)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|||||||
Reference in New Issue
Block a user