Skip to content
Open
6 changes: 1 addition & 5 deletions server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from server.lib.disaster_dashboard import get_disaster_dashboard_data
from server.lib.feature_flags import BIOMED_NL_FEATURE_FLAG
from server.lib.feature_flags import DATA_OVERVIEW_FEATURE_FLAG
from server.lib.feature_flags import ENABLE_GEMINI_3_FLASH
from server.lib.feature_flags import ENABLE_NL_AGENT_DETECTOR
from server.lib.feature_flags import is_feature_enabled
import server.lib.i18n as i18n
Expand Down Expand Up @@ -435,10 +434,7 @@ def create_app(nl_root=DEFAULT_NL_ROOT):
'palm-api-key')
if is_feature_enabled(ENABLE_NL_AGENT_DETECTOR, app):
os.environ['GEMINI_API_KEY'] = app.config['LLM_API_KEY']
if is_feature_enabled(ENABLE_GEMINI_3_FLASH, app):
default_model = "gemini-3-flash-preview"
else:
default_model = "gemini-2.5-flash"
default_model = "gemini-3-flash-preview"
app.config['NL_DETECTION_AGENT'] = create_detection_agent(
os.environ.get("AGENT_MODEL", default_model),
os.environ.get("DC_MCP_URL"))
Expand Down
1 change: 0 additions & 1 deletion server/lib/feature_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
ENABLE_STAT_VAR_AUTOCOMPLETE = 'enable_stat_var_autocomplete'
ENABLE_NL_AGENT_DETECTOR = 'enable_nl_agent_detector'
NEW_RANKING_PAGE = 'new_ranking_page'
ENABLE_GEMINI_3_FLASH = 'enable_gemini_3_flash'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this PR is released to 2 prod cycles, make sure to delete the feature flag from the feature flag .json files!

2 prod cycles so that if we have to do a rollback at some point, it's still safe!

USE_V2_API = 'use_v2_api'
# This flag controls the switching of detect-and-fulfill API to use v2/resolve from current nl search vars
USE_V2_RESOLVE_FOR_NL_SEARCH_VARS = 'use_v2_resolve_for_nl_search_vars'
Expand Down
16 changes: 2 additions & 14 deletions server/lib/nl/detection/llm_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@
from google.genai import types
import json5

from server.lib.feature_flags import ENABLE_GEMINI_3_FLASH
from server.lib.feature_flags import is_feature_enabled
from server.lib.nl.common import counters

_GEMINI_3_0_FLASH = 'gemini-3-flash-preview'
_GEMINI_2_5_FLASH = 'gemini-2.5-flash'
_API_VERSION_3 = 'v1beta'
_API_VERSION_2 = 'v1'

# TODO: Consider tweaking this. And maybe consider passing as url param.
_TEMPERATURE = 0.1
Expand All @@ -55,13 +51,7 @@
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
])

_GEMINI_2_5_CONFIG = _GEMINI_CONFIG

_GEMINI_3_CONFIG = types.GenerateContentConfig(
temperature=_TEMPERATURE,
safety_settings=_GEMINI_CONFIG.safety_settings,
],
thinking_config=types.ThinkingConfig(thinking_level="low"))

_SKIP_BEGIN_CHARS = ['`', '*']
Expand Down Expand Up @@ -197,6 +187,4 @@ def _extract_answer(resp: str) -> str:


def detect_model_name() -> tuple[str, str, types.GenerateContentConfig]:
if is_feature_enabled(ENABLE_GEMINI_3_FLASH):
return _GEMINI_3_0_FLASH, _API_VERSION_3, _GEMINI_3_CONFIG
return _GEMINI_2_5_FLASH, _API_VERSION_2, _GEMINI_2_5_CONFIG
return _GEMINI_3_0_FLASH, _API_VERSION_3, _GEMINI_CONFIG
10 changes: 2 additions & 8 deletions server/lib/nl/explore/overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
from pydantic import ConfigDict
from pydantic.alias_generators import to_camel

from server.lib.feature_flags import ENABLE_GEMINI_3_FLASH
from server.lib.feature_flags import is_feature_enabled
from server.lib.nl.explore.gemini_prompts import PAGE_OVERVIEW_PROMPT
from server.lib.utils.gemini_utils import call_gemini

Expand Down Expand Up @@ -81,12 +79,8 @@ def generate_page_overview(
formatted_page_overview_prompt = PAGE_OVERVIEW_PROMPT.format(
initial_query=query, stat_var_titles=stat_var_titles)

if is_feature_enabled(ENABLE_GEMINI_3_FLASH):
overview_gemini_model = _OVERVIEW_GEMINI_3_1_LITE
use_thinking_config = True
else:
overview_gemini_model = _OVERVIEW_GEMINI_2_5_LITE
use_thinking_config = False
overview_gemini_model = _OVERVIEW_GEMINI_3_1_LITE
use_thinking_config = True

page_overview = call_gemini(api_key=gemini_api_key,
formatted_prompt=formatted_page_overview_prompt,
Expand Down
10 changes: 2 additions & 8 deletions server/lib/nl/explore/related.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
from flask import current_app
from pydantic import BaseModel

from server.lib.feature_flags import ENABLE_GEMINI_3_FLASH
from server.lib.feature_flags import is_feature_enabled
import server.lib.nl.common.topic as topic
import server.lib.nl.common.utils as utils
import server.lib.nl.detection.types as dtypes
Expand Down Expand Up @@ -316,12 +314,8 @@ def generate_follow_up_questions(query: str,
formatted_follow_up_questions_prompt = FOLLOW_UP_QUESTIONS_PROMPT.format(
initial_query=query, related_topics=related_topics)

if is_feature_enabled(ENABLE_GEMINI_3_FLASH):
gemini_model = _QUESTIONS_GEMINI_3
use_thinking_config = True
else:
gemini_model = _QUESTIONS_GEMINI_2
use_thinking_config = False
gemini_model = _QUESTIONS_GEMINI_3
use_thinking_config = True

follow_up_questions = call_gemini(
api_key=gemini_api_key,
Expand Down
14 changes: 5 additions & 9 deletions server/lib/utils/gemini_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,34 @@
from pydantic import BaseModel


def get_gemini_config(schema: Optional[BaseModel] = None,
use_thinking_config: bool = False) -> dict:
def get_gemini_config(schema: Optional[BaseModel] = None) -> dict:
config = {
"response_mime_type": "application/json",
"response_schema": schema
"response_schema": schema,
"thinking_config": genai.types.ThinkingConfig(thinking_level="low")
} if schema else {}
if use_thinking_config:
config["thinking_config"] = genai.types.ThinkingConfig(thinking_level="low")
return config


def call_gemini(
api_key: str,
formatted_prompt: str,
gemini_model: str,
schema: Optional[BaseModel] = None,
use_thinking_config: bool = False) -> Optional[Union[BaseModel, str]]:
schema: Optional[BaseModel] = None) -> Optional[Union[BaseModel, str]]:
"""A helper for all Gemini generations through the Python Gen AI client.
Args:
api_key: A string representing the API key required for authentication with the Gemini service.
formatted_prompt: A string containing the structured prompt or input to be sent to the Gemini model for generation.
schema: A Pydantic BaseModel class that defines the expected model's JSON response.
gemini_model: A string specifying the name of the Gemini model to utilize.
use_thinking_config: Boolean advising whether to use thinking configuration for Gemini 3.

Returns:
The output of the call.
"""
if not api_key or not formatted_prompt:
return None

generate_content_config = get_gemini_config(schema, use_thinking_config)
generate_content_config = get_gemini_config(schema)
gemini = genai.Client(api_key=api_key)

try:
Expand Down
Loading