Spaces:
Paused
Paused
Mirrowel commited on
Commit ·
7785a1f
1
Parent(s): eddf03f
chore(config): ⚙️ enable conditional instantiation of API call persistence
Browse filesThis change introduces a global runtime flag to gate the creation of detailed, per-request log directories within the Gemini CLI provider plugin.
By default, the internal file logger for Gemini requests is now disabled, preventing unnecessary I/O operations and resource consumption from creating unique log files for every transaction. The system only initializes the logging infrastructure and interacts with the file system if `enable_request_logging` is explicitly set to true upon client initialization.
- Introduce `enable_request_logging` parameter in RotatingClient.
- Condition the file logger's directory creation on the new flag.
- Suppress verbose console debugging output that duplicates file logging.
src/proxy_app/main.py
CHANGED
|
@@ -282,9 +282,10 @@ async def lifespan(app: FastAPI):
|
|
| 282 |
api_keys=api_keys,
|
| 283 |
oauth_credentials=oauth_credentials, # Pass OAuth config
|
| 284 |
configure_logging=True,
|
| 285 |
-
litellm_provider_params=litellm_provider_params,
|
| 286 |
ignore_models=ignore_models,
|
| 287 |
-
whitelist_models=whitelist_models
|
|
|
|
| 288 |
)
|
| 289 |
client.background_refresher.start() # Start the background task
|
| 290 |
app.state.rotating_client = client
|
|
|
|
| 282 |
api_keys=api_keys,
|
| 283 |
oauth_credentials=oauth_credentials, # Pass OAuth config
|
| 284 |
configure_logging=True,
|
| 285 |
+
litellm_provider_params=litellm_provider_params,
|
| 286 |
ignore_models=ignore_models,
|
| 287 |
+
whitelist_models=whitelist_models,
|
| 288 |
+
enable_request_logging=ENABLE_REQUEST_LOGGING
|
| 289 |
)
|
| 290 |
client.background_refresher.start() # Start the background task
|
| 291 |
app.state.rotating_client = client
|
src/rotator_library/client.py
CHANGED
|
@@ -47,9 +47,10 @@ class RotatingClient:
|
|
| 47 |
configure_logging: bool = True,
|
| 48 |
global_timeout: int = 30,
|
| 49 |
abort_on_callback_error: bool = True,
|
| 50 |
-
litellm_provider_params: Optional[Dict[str, Any]] = None,
|
| 51 |
ignore_models: Optional[Dict[str, List[str]]] = None,
|
| 52 |
-
whitelist_models: Optional[Dict[str, List[str]]] = None
|
|
|
|
| 53 |
):
|
| 54 |
os.environ["LITELLM_LOG"] = "ERROR"
|
| 55 |
litellm.set_verbose = False
|
|
@@ -93,6 +94,7 @@ class RotatingClient:
|
|
| 93 |
self.litellm_provider_params = litellm_provider_params or {}
|
| 94 |
self.ignore_models = ignore_models or {}
|
| 95 |
self.whitelist_models = whitelist_models or {}
|
|
|
|
| 96 |
|
| 97 |
def _is_model_ignored(self, provider: str, model_id: str) -> bool:
|
| 98 |
"""
|
|
@@ -448,6 +450,7 @@ class RotatingClient:
|
|
| 448 |
if provider_plugin and provider_plugin.has_custom_logic():
|
| 449 |
lib_logger.debug(f"Provider '{provider}' has custom logic. Delegating call.")
|
| 450 |
litellm_kwargs["credential_identifier"] = current_cred
|
|
|
|
| 451 |
|
| 452 |
# Check body first for custom_reasoning_budget
|
| 453 |
if "custom_reasoning_budget" in kwargs:
|
|
@@ -668,6 +671,7 @@ class RotatingClient:
|
|
| 668 |
if provider_plugin and provider_plugin.has_custom_logic():
|
| 669 |
lib_logger.debug(f"Provider '{provider}' has custom logic. Delegating call.")
|
| 670 |
litellm_kwargs["credential_identifier"] = current_cred
|
|
|
|
| 671 |
|
| 672 |
for attempt in range(self.max_retries):
|
| 673 |
try:
|
|
|
|
| 47 |
configure_logging: bool = True,
|
| 48 |
global_timeout: int = 30,
|
| 49 |
abort_on_callback_error: bool = True,
|
| 50 |
+
litellm_provider_params: Optional[Dict[str, Any]] = None,
|
| 51 |
ignore_models: Optional[Dict[str, List[str]]] = None,
|
| 52 |
+
whitelist_models: Optional[Dict[str, List[str]]] = None,
|
| 53 |
+
enable_request_logging: bool = False
|
| 54 |
):
|
| 55 |
os.environ["LITELLM_LOG"] = "ERROR"
|
| 56 |
litellm.set_verbose = False
|
|
|
|
| 94 |
self.litellm_provider_params = litellm_provider_params or {}
|
| 95 |
self.ignore_models = ignore_models or {}
|
| 96 |
self.whitelist_models = whitelist_models or {}
|
| 97 |
+
self.enable_request_logging = enable_request_logging
|
| 98 |
|
| 99 |
def _is_model_ignored(self, provider: str, model_id: str) -> bool:
|
| 100 |
"""
|
|
|
|
| 450 |
if provider_plugin and provider_plugin.has_custom_logic():
|
| 451 |
lib_logger.debug(f"Provider '{provider}' has custom logic. Delegating call.")
|
| 452 |
litellm_kwargs["credential_identifier"] = current_cred
|
| 453 |
+
litellm_kwargs["enable_request_logging"] = self.enable_request_logging
|
| 454 |
|
| 455 |
# Check body first for custom_reasoning_budget
|
| 456 |
if "custom_reasoning_budget" in kwargs:
|
|
|
|
| 671 |
if provider_plugin and provider_plugin.has_custom_logic():
|
| 672 |
lib_logger.debug(f"Provider '{provider}' has custom logic. Delegating call.")
|
| 673 |
litellm_kwargs["credential_identifier"] = current_cred
|
| 674 |
+
litellm_kwargs["enable_request_logging"] = self.enable_request_logging
|
| 675 |
|
| 676 |
for attempt in range(self.max_retries):
|
| 677 |
try:
|
src/rotator_library/providers/gemini_cli_provider.py
CHANGED
|
@@ -23,7 +23,11 @@ GEMINI_CLI_LOGS_DIR = LOGS_DIR / "gemini_cli_logs"
|
|
| 23 |
|
| 24 |
class _GeminiCliFileLogger:
|
| 25 |
"""A simple file logger for a single Gemini CLI transaction."""
|
| 26 |
-
def __init__(self, model_name: str):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
| 28 |
request_id = str(uuid.uuid4())
|
| 29 |
# Sanitize model name for directory
|
|
@@ -31,7 +35,6 @@ class _GeminiCliFileLogger:
|
|
| 31 |
self.log_dir = GEMINI_CLI_LOGS_DIR / f"{timestamp}_{safe_model_name}_{request_id}"
|
| 32 |
try:
|
| 33 |
self.log_dir.mkdir(parents=True, exist_ok=True)
|
| 34 |
-
self.enabled = True
|
| 35 |
except Exception as e:
|
| 36 |
lib_logger.error(f"Failed to create Gemini CLI log directory: {e}")
|
| 37 |
self.enabled = False
|
|
@@ -519,6 +522,7 @@ class GeminiCliProvider(GeminiAuthBase, ProviderInterface):
|
|
| 519 |
async def acompletion(self, client: httpx.AsyncClient, **kwargs) -> Union[litellm.ModelResponse, AsyncGenerator[litellm.ModelResponse, None]]:
|
| 520 |
model = kwargs["model"]
|
| 521 |
credential_path = kwargs.pop("credential_identifier")
|
|
|
|
| 522 |
|
| 523 |
async def do_call():
|
| 524 |
# Get auth header once, it's needed for the request anyway
|
|
@@ -534,7 +538,10 @@ class GeminiCliProvider(GeminiAuthBase, ProviderInterface):
|
|
| 534 |
model_name = model.split('/')[-1].replace(':thinking', '')
|
| 535 |
|
| 536 |
# [NEW] Create a dedicated file logger for this request
|
| 537 |
-
file_logger = _GeminiCliFileLogger(
|
|
|
|
|
|
|
|
|
|
| 538 |
|
| 539 |
gen_config = {
|
| 540 |
"maxOutputTokens": kwargs.get("max_tokens", 64000), # Increased default
|
|
@@ -578,7 +585,7 @@ class GeminiCliProvider(GeminiAuthBase, ProviderInterface):
|
|
| 578 |
request_payload["request"]["toolConfig"] = tool_config
|
| 579 |
|
| 580 |
# Log the final payload for debugging and to the dedicated file
|
| 581 |
-
lib_logger.debug(f"Gemini CLI Request Payload: {json.dumps(request_payload, indent=2)}")
|
| 582 |
file_logger.log_request(request_payload)
|
| 583 |
|
| 584 |
url = f"{CODE_ASSIST_ENDPOINT}:streamGenerateContent"
|
|
|
|
| 23 |
|
| 24 |
class _GeminiCliFileLogger:
|
| 25 |
"""A simple file logger for a single Gemini CLI transaction."""
|
| 26 |
+
def __init__(self, model_name: str, enabled: bool = True):
|
| 27 |
+
self.enabled = enabled
|
| 28 |
+
if not self.enabled:
|
| 29 |
+
return
|
| 30 |
+
|
| 31 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
| 32 |
request_id = str(uuid.uuid4())
|
| 33 |
# Sanitize model name for directory
|
|
|
|
| 35 |
self.log_dir = GEMINI_CLI_LOGS_DIR / f"{timestamp}_{safe_model_name}_{request_id}"
|
| 36 |
try:
|
| 37 |
self.log_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
| 38 |
except Exception as e:
|
| 39 |
lib_logger.error(f"Failed to create Gemini CLI log directory: {e}")
|
| 40 |
self.enabled = False
|
|
|
|
| 522 |
async def acompletion(self, client: httpx.AsyncClient, **kwargs) -> Union[litellm.ModelResponse, AsyncGenerator[litellm.ModelResponse, None]]:
|
| 523 |
model = kwargs["model"]
|
| 524 |
credential_path = kwargs.pop("credential_identifier")
|
| 525 |
+
enable_request_logging = kwargs.pop("enable_request_logging", False)
|
| 526 |
|
| 527 |
async def do_call():
|
| 528 |
# Get auth header once, it's needed for the request anyway
|
|
|
|
| 538 |
model_name = model.split('/')[-1].replace(':thinking', '')
|
| 539 |
|
| 540 |
# [NEW] Create a dedicated file logger for this request
|
| 541 |
+
file_logger = _GeminiCliFileLogger(
|
| 542 |
+
model_name=model_name,
|
| 543 |
+
enabled=enable_request_logging
|
| 544 |
+
)
|
| 545 |
|
| 546 |
gen_config = {
|
| 547 |
"maxOutputTokens": kwargs.get("max_tokens", 64000), # Increased default
|
|
|
|
| 585 |
request_payload["request"]["toolConfig"] = tool_config
|
| 586 |
|
| 587 |
# Log the final payload for debugging and to the dedicated file
|
| 588 |
+
#lib_logger.debug(f"Gemini CLI Request Payload: {json.dumps(request_payload, indent=2)}")
|
| 589 |
file_logger.log_request(request_payload)
|
| 590 |
|
| 591 |
url = f"{CODE_ASSIST_ENDPOINT}:streamGenerateContent"
|