#!/usr/bin/env python3
"""
Demonstration of Search Provider Timeout Fixes
This script shows how the timeout issues identified by the debugger subagent have been resolved:
BEFORE (Issues):
- Complex queries failed at exactly 10 seconds
- Circuit breakers were too aggressive (5 failures = disabled)
- No distinction between timeout and other failure types
- Budget allocation wasn't optimal
AFTER (Fixed):
- Complex queries get up to 25 seconds
- Circuit breakers are more tolerant (8 failures, faster recovery)
- Timeout failures have separate, higher threshold (12 vs 6)
- Better budget allocation with minimum timeout protection
"""
import sys
from pathlib import Path
from maverick_mcp.agents.deep_research import WebSearchProvider
from maverick_mcp.config.settings import get_settings
# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
def demonstrate_timeout_improvements():
"""Show the specific improvements made to resolve timeout issues."""
print("π SEARCH PROVIDER TIMEOUT FIXES")
print("=" * 50)
# Create test provider to demonstrate calculations
class DemoProvider(WebSearchProvider):
async def search(self, query, num_results=10, timeout_budget=None):
return []
provider = DemoProvider(api_key="demo")
settings = get_settings()
# The problematic query from the debugger report
complex_query = "Google Microsoft OpenAI AI services competition revenue market share 2024 2025 growth forecast Claude Gemini GPT"
print("π COMPLEX QUERY EXAMPLE:")
print(f" Query: {complex_query}")
print(f" Words: {len(complex_query.split())}")
# Show timeout calculation
timeout = provider._calculate_timeout(complex_query)
print(f" β
NEW Timeout: {timeout:.1f}s (was 10s β now 25s)")
# Show budget scenarios
tight_budget_timeout = provider._calculate_timeout(
complex_query, timeout_budget=15.0
)
good_budget_timeout = provider._calculate_timeout(
complex_query, timeout_budget=50.0
)
print(f" β
With 15s budget: {tight_budget_timeout:.1f}s (min 8s protection)")
print(f" β
With 50s budget: {good_budget_timeout:.1f}s (full 25s)")
print("\nπ FAILURE TOLERANCE IMPROVEMENTS:")
# Show tolerance thresholds
timeout_threshold = getattr(
settings.performance, "search_timeout_failure_threshold", 12
)
circuit_threshold = getattr(
settings.performance, "search_circuit_breaker_failure_threshold", 8
)
circuit_recovery = getattr(
settings.performance, "search_circuit_breaker_recovery_timeout", 30
)
print(f" β
Timeout failures before disable: {timeout_threshold} (was 3)")
print(f" β
Circuit breaker threshold: {circuit_threshold} (was 5)")
print(f" β
Circuit breaker recovery: {circuit_recovery}s (was 60s)")
print("\nπ― KEY FIXES SUMMARY:")
print(" β
Complex queries (9+ words): 25s timeout instead of 10s")
print(" β
Medium queries (4-8 words): 17s timeout instead of 10s")
print(" β
Minimum timeout protection: Never below 8s for complex queries")
print(" β
Budget efficiency: 85% allocation (was 80%)")
print(" β
Timeout-specific tolerance: 12 failures (was 3)")
print(" β
Search circuit breakers: 8 failures, 30s recovery")
print("\n㪠TECHNICAL DETAILS:")
print(" β’ Timeout calculation is adaptive based on query complexity")
print(" β’ Budget constraints respect minimum timeout requirements")
print(" β’ Separate failure tracking for timeout vs other errors")
print(" β’ Circuit breakers tuned specifically for search operations")
print(" β’ Enhanced debug logging for troubleshooting")
def show_before_after_comparison():
"""Show specific before/after comparisons for the identified issues."""
print("\nπ BEFORE vs AFTER COMPARISON")
print("=" * 50)
test_cases = [
("AAPL", "Simple 1-word query"),
("Google Microsoft OpenAI competition", "Medium 4-word query"),
(
"Google Microsoft OpenAI AI services competition revenue market share 2024 2025 growth forecast",
"Complex 13-word query",
),
]
for query, description in test_cases:
words = len(query.split())
# Calculate OLD timeout (all queries got 10s)
old_timeout = 10.0
# Calculate NEW timeout
provider = WebSearchProvider(api_key="demo")
new_timeout = provider._calculate_timeout(query)
improvement = "π°" if old_timeout == new_timeout else "π"
print(f" {improvement} {description} ({words} words):")
print(f" BEFORE: {old_timeout:.1f}s | AFTER: {new_timeout:.1f}s")
if __name__ == "__main__":
demonstrate_timeout_improvements()
show_before_after_comparison()
print("\nβ
The search provider timeout issues have been fully resolved!")
print(
" Complex queries like the 15-word example will now get 25s instead of failing at 10s."
)