Spaces:
Running
Running
""" | |
Configuration constants for the Geminicli2api proxy server. | |
Centralizes all configuration to avoid duplication across modules. | |
""" | |
import os | |
# API Endpoints | |
CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com" | |
# Client Configuration | |
CLI_VERSION = "0.1.5" # Match current gemini-cli version | |
# OAuth Configuration | |
CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" | |
CLIENT_SECRET = "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" | |
SCOPES = [ | |
"https://www.googleapis.com/auth/cloud-platform", | |
"https://www.googleapis.com/auth/userinfo.email", | |
"https://www.googleapis.com/auth/userinfo.profile", | |
] | |
# File Paths | |
SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
CREDENTIAL_FILE = os.path.join(SCRIPT_DIR, os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "oauth_creds.json")) | |
# Authentication | |
GEMINI_AUTH_PASSWORD = os.getenv("GEMINI_AUTH_PASSWORD", "123456") | |
# Default Safety Settings for Google API | |
DEFAULT_SAFETY_SETTINGS = [ | |
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"}, | |
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"}, | |
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"}, | |
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"}, | |
{"category": "HARM_CATEGORY_CIVIC_INTEGRITY", "threshold": "BLOCK_NONE"} | |
] | |
# Base Models (without search variants) | |
BASE_MODELS = [ | |
{ | |
"name": "models/gemini-2.5-pro-preview-05-06", | |
"version": "001", | |
"displayName": "Gemini 2.5 Pro Preview 05-06", | |
"description": "Preview version of Gemini 2.5 Pro from May 6th", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
}, | |
{ | |
"name": "models/gemini-2.5-pro-preview-06-05", | |
"version": "001", | |
"displayName": "Gemini 2.5 Pro Preview 06-05", | |
"description": "Preview version of Gemini 2.5 Pro from June 5th", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
}, | |
{ | |
"name": "models/gemini-2.5-pro", | |
"version": "001", | |
"displayName": "Gemini 2.5 Pro", | |
"description": "Advanced multimodal model with enhanced capabilities", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
}, | |
{ | |
"name": "models/gemini-2.5-flash-preview-05-20", | |
"version": "001", | |
"displayName": "Gemini 2.5 Flash Preview 05-20", | |
"description": "Preview version of Gemini 2.5 Flash from May 20th", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
}, | |
{ | |
"name": "models/gemini-2.5-flash-preview-04-17", | |
"version": "001", | |
"displayName": "Gemini 2.5 Flash Preview 04-17", | |
"description": "Preview version of Gemini 2.5 Flash from April 17th", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
}, | |
{ | |
"name": "models/gemini-2.5-flash", | |
"version": "001", | |
"displayName": "Gemini 2.5 Flash", | |
"description": "Fast and efficient multimodal model with latest improvements", | |
"inputTokenLimit": 1048576, | |
"outputTokenLimit": 65535, | |
"supportedGenerationMethods": ["generateContent", "streamGenerateContent"], | |
"temperature": 1.0, | |
"maxTemperature": 2.0, | |
"topP": 0.95, | |
"topK": 64 | |
} | |
] | |
# Generate search variants for applicable models | |
def _generate_search_variants(): | |
"""Generate search variants for models that support content generation.""" | |
search_models = [] | |
for model in BASE_MODELS: | |
# Only add search variants for models that support content generation | |
if "generateContent" in model["supportedGenerationMethods"]: | |
search_variant = model.copy() | |
search_variant["name"] = model["name"] + "-search" | |
search_variant["displayName"] = model["displayName"] + " with Google Search" | |
search_variant["description"] = model["description"] + " (includes Google Search grounding)" | |
search_models.append(search_variant) | |
return search_models | |
# Generate thinking variants for applicable models | |
def _generate_thinking_variants(): | |
"""Generate nothinking and maxthinking variants for models that support thinking.""" | |
thinking_models = [] | |
for model in BASE_MODELS: | |
# Only add thinking variants for models that support content generation | |
# and contain "gemini-2.5-flash" or "gemini-2.5-pro" in their name | |
if ("generateContent" in model["supportedGenerationMethods"] and | |
("gemini-2.5-flash" in model["name"] or "gemini-2.5-pro" in model["name"])): | |
# Add -nothinking variant | |
nothinking_variant = model.copy() | |
nothinking_variant["name"] = model["name"] + "-nothinking" | |
nothinking_variant["displayName"] = model["displayName"] + " (No Thinking)" | |
nothinking_variant["description"] = model["description"] + " (thinking disabled)" | |
thinking_models.append(nothinking_variant) | |
# Add -maxthinking variant | |
maxthinking_variant = model.copy() | |
maxthinking_variant["name"] = model["name"] + "-maxthinking" | |
maxthinking_variant["displayName"] = model["displayName"] + " (Max Thinking)" | |
maxthinking_variant["description"] = model["description"] + " (maximum thinking budget)" | |
thinking_models.append(maxthinking_variant) | |
return thinking_models | |
# Generate combined variants (search + thinking combinations) | |
def _generate_combined_variants(): | |
"""Generate combined search and thinking variants.""" | |
combined_models = [] | |
for model in BASE_MODELS: | |
# Only add combined variants for models that support content generation | |
# and contain "gemini-2.5-flash" or "gemini-2.5-pro" in their name | |
if ("generateContent" in model["supportedGenerationMethods"] and | |
("gemini-2.5-flash" in model["name"] or "gemini-2.5-pro" in model["name"])): | |
# search + nothinking | |
search_nothinking = model.copy() | |
search_nothinking["name"] = model["name"] + "-search-nothinking" | |
search_nothinking["displayName"] = model["displayName"] + " with Google Search (No Thinking)" | |
search_nothinking["description"] = model["description"] + " (includes Google Search grounding, thinking disabled)" | |
combined_models.append(search_nothinking) | |
# search + maxthinking | |
search_maxthinking = model.copy() | |
search_maxthinking["name"] = model["name"] + "-search-maxthinking" | |
search_maxthinking["displayName"] = model["displayName"] + " with Google Search (Max Thinking)" | |
search_maxthinking["description"] = model["description"] + " (includes Google Search grounding, maximum thinking budget)" | |
combined_models.append(search_maxthinking) | |
return combined_models | |
# Supported Models (includes base models, search variants, and thinking variants) | |
# Combine all models and then sort them by name to group variants together | |
all_models = BASE_MODELS + _generate_search_variants() + _generate_thinking_variants() | |
SUPPORTED_MODELS = sorted(all_models, key=lambda x: x['name']) | |
# Helper function to get base model name from any variant | |
def get_base_model_name(model_name): | |
"""Convert variant model name to base model name.""" | |
# Remove all possible suffixes in order | |
suffixes = ["-maxthinking", "-nothinking", "-search"] | |
for suffix in suffixes: | |
if model_name.endswith(suffix): | |
return model_name[:-len(suffix)] | |
return model_name | |
# Helper function to check if model uses search grounding | |
def is_search_model(model_name): | |
"""Check if model name indicates search grounding should be enabled.""" | |
return "-search" in model_name | |
# Helper function to check if model uses no thinking | |
def is_nothinking_model(model_name): | |
"""Check if model name indicates thinking should be disabled.""" | |
return "-nothinking" in model_name | |
# Helper function to check if model uses max thinking | |
def is_maxthinking_model(model_name): | |
"""Check if model name indicates maximum thinking budget should be used.""" | |
return "-maxthinking" in model_name | |
# Helper function to get thinking budget for a model | |
def get_thinking_budget(model_name): | |
"""Get the appropriate thinking budget for a model based on its name and variant.""" | |
base_model = get_base_model_name(model_name) | |
if is_nothinking_model(model_name): | |
if "gemini-2.5-flash" in base_model: | |
return 0 # No thinking for flash | |
elif "gemini-2.5-pro" in base_model: | |
return 128 # Limited thinking for pro | |
elif is_maxthinking_model(model_name): | |
if "gemini-2.5-flash" in base_model: | |
return 24576 | |
elif "gemini-2.5-pro" in base_model: | |
return 32768 | |
else: | |
# Default thinking budget for regular models | |
return -1 # Default for all models | |
# Helper function to check if thinking should be included in output | |
def should_include_thoughts(model_name): | |
"""Check if thoughts should be included in the response.""" | |
if is_nothinking_model(model_name): | |
# For nothinking mode, still include thoughts if it's a pro model | |
base_model = get_base_model_name(model_name) | |
return "gemini-2.5-pro" in base_model | |
else: | |
# For all other modes, include thoughts | |
return True |