Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions astrbot/core/provider/sources/gemini_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,17 +251,22 @@ async def _prepare_query_config(
)
if thinking_level and isinstance(thinking_level, str):
thinking_level = thinking_level.upper()
if thinking_level not in ["MINIMAL", "LOW", "MEDIUM", "HIGH"]:
allowed_levels = {"MINIMAL", "LOW", "MEDIUM", "HIGH"}
fallback_level = "HIGH"
if model_name.startswith("gemini-3.7"):
allowed_levels = {"LOW", "MEDIUM", "HIGH"}
fallback_level = "MEDIUM"
if thinking_level not in allowed_levels:
logger.warning(
f"Invalid thinking level: {thinking_level}, using HIGH"
"Invalid thinking level %s for %s, using %s",
thinking_level,
model_name,
fallback_level,
)
thinking_level = "HIGH"
level = types.ThinkingLevel(thinking_level)
thinking_config = types.ThinkingConfig()
if not hasattr(types.ThinkingConfig, "thinking_level"):
setattr(types.ThinkingConfig, "thinking_level", level)
else:
thinking_config.thinking_level = level
thinking_level = fallback_level
thinking_config = types.ThinkingConfig(
thinking_level=types.ThinkingLevel(thinking_level)
)

return types.GenerateContentConfig(
system_instruction=system_instruction,
Expand Down
39 changes: 39 additions & 0 deletions tests/test_gemini_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,45 @@
from astrbot.core.provider.sources.gemini_source import ProviderGoogleGenAI


@pytest.mark.asyncio
async def test_gemini_thinking_level_is_serialized_on_every_request():
model = "gemini-3.7-flash"
provider = ProviderGoogleGenAI.__new__(ProviderGoogleGenAI)
provider.provider_config = {"gm_thinking_config": {"level": "HIGH"}}
provider.provider_settings = {}
provider.model_name = model
provider.safety_settings = []

first_config = await provider._prepare_query_config({"model": model})
second_config = await provider._prepare_query_config({"model": model})

assert first_config.thinking_config is not None
assert second_config.thinking_config is not None
assert first_config.thinking_config.model_dump(exclude_none=True) == {
"thinking_level": types.ThinkingLevel.HIGH,
}
assert second_config.thinking_config.model_dump(exclude_none=True) == {
"thinking_level": types.ThinkingLevel.HIGH,
}


@pytest.mark.asyncio
async def test_gemini_37_minimal_thinking_level_falls_back_to_medium():
model = "gemini-3.7-flash"
provider = ProviderGoogleGenAI.__new__(ProviderGoogleGenAI)
provider.provider_config = {"gm_thinking_config": {"level": "MINIMAL"}}
provider.provider_settings = {}
provider.model_name = model
provider.safety_settings = []

config = await provider._prepare_query_config({"model": model})

assert config.thinking_config is not None
assert config.thinking_config.model_dump(exclude_none=True) == {
"thinking_level": types.ThinkingLevel.MEDIUM,
}


@pytest.mark.asyncio
async def test_gemini_prepare_conversation_removes_leading_model_content():
provider = ProviderGoogleGenAI.__new__(ProviderGoogleGenAI)
Expand Down
Loading