Skip to content

Commit 6a7aef9

Browse files
committed
fix proxy
1 parent d9699ad commit 6a7aef9

File tree

5 files changed

+64
-22
lines changed

5 files changed

+64
-22
lines changed

optillm/plugins/proxy/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""OptiLLM Proxy Plugin - Load balancing and failover for LLM providers"""
22

3-
from .config import ProxyConfig
4-
from .client import ProxyClient
5-
from .routing import RouterFactory
6-
from .health import HealthChecker
3+
from optillm.plugins.proxy.config import ProxyConfig
4+
from optillm.plugins.proxy.client import ProxyClient
5+
from optillm.plugins.proxy.routing import RouterFactory
6+
from optillm.plugins.proxy.health import HealthChecker
77

88
__all__ = ['ProxyConfig', 'ProxyClient', 'RouterFactory', 'HealthChecker']

optillm/plugins/proxy/client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import random
77
from typing import Dict, List, Any, Optional
88
from openai import OpenAI, AzureOpenAI
9-
from .routing import RouterFactory
10-
from .health import HealthChecker
9+
from optillm.plugins.proxy.routing import RouterFactory
10+
from optillm.plugins.proxy.health import HealthChecker
1111

1212
logger = logging.getLogger(__name__)
1313

@@ -137,6 +137,7 @@ def create(self, **kwargs):
137137
break
138138

139139
provider = self.proxy_client.router.select(available_providers)
140+
logger.info(f"Router selected provider: {provider.name if provider else 'None'}")
140141

141142
if not provider:
142143
break

optillm/plugins/proxy/routing.py

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22
Routing strategies for load balancing across providers.
33
"""
44
import random
5+
import logging
56
from typing import List, Optional
67
from abc import ABC, abstractmethod
78

9+
# Configure logging for this module
10+
logger = logging.getLogger(__name__)
11+
# Ensure we show debug messages
12+
logging.basicConfig()
13+
logger.setLevel(logging.DEBUG)
14+
815
class Router(ABC):
916
"""Abstract base class for routing strategies"""
1017

@@ -17,21 +24,44 @@ class RoundRobinRouter(Router):
1724
"""Round-robin routing strategy"""
1825

1926
def __init__(self, providers: List):
20-
self.providers = providers
27+
self.all_providers = providers
2128
self.index = 0
2229

2330
def select(self, providers: List) -> Optional:
2431
if not providers:
32+
logger.debug("Round-robin: No providers available")
2533
return None
2634

27-
# Find next available provider
28-
for _ in range(len(providers)):
29-
provider = self.providers[self.index % len(self.providers)]
30-
self.index += 1
31-
if provider in providers:
32-
return provider
35+
# If only one provider available, return it
36+
if len(providers) == 1:
37+
logger.debug(f"Round-robin: Only one provider: {providers[0].name}")
38+
return providers[0]
3339

34-
return providers[0] if providers else None
40+
logger.debug(f"Round-robin: Starting selection, index={self.index}, providers={[p.name for p in providers]}")
41+
42+
# Find next available provider in round-robin fashion
43+
start_index = self.index
44+
attempts = 0
45+
while attempts < len(self.all_providers):
46+
# Get provider at current index from all providers
47+
current_provider = self.all_providers[self.index % len(self.all_providers)]
48+
next_index = (self.index + 1) % len(self.all_providers)
49+
50+
logger.debug(f"Round-robin: Checking provider {current_provider.name} at index {self.index}")
51+
52+
# Update index for next call
53+
self.index = next_index
54+
55+
# If this provider is in the available list, use it
56+
if current_provider in providers:
57+
logger.debug(f"Round-robin: Selected provider {current_provider.name}")
58+
return current_provider
59+
60+
attempts += 1
61+
62+
# If we've cycled through all providers, just return first available
63+
logger.debug(f"Round-robin: Fallback to first available: {providers[0].name}")
64+
return providers[0]
3565

3666
class WeightedRouter(Router):
3767
"""Weighted random routing strategy"""

optillm/plugins/proxy_plugin.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"""
77
import logging
88
from typing import Tuple, Optional
9-
from .proxy.config import ProxyConfig
10-
from .proxy.client import ProxyClient
11-
from .proxy.approach_handler import ApproachHandler
9+
from optillm.plugins.proxy.config import ProxyConfig
10+
from optillm.plugins.proxy.client import ProxyClient
11+
from optillm.plugins.proxy.approach_handler import ApproachHandler
1212

1313
SLUG = "proxy"
1414
logger = logging.getLogger(__name__)
@@ -18,6 +18,9 @@
1818
log_level = os.environ.get('OPTILLM_LOG_LEVEL', 'INFO')
1919
logging.basicConfig(level=getattr(logging, log_level))
2020

21+
# Global proxy client cache to maintain state between requests
22+
_proxy_client_cache = {}
23+
2124
def run(system_prompt: str, initial_query: str, client, model: str,
2225
request_config: dict = None) -> Tuple[str, int]:
2326
"""
@@ -53,11 +56,18 @@ def run(system_prompt: str, initial_query: str, client, model: str,
5356
)
5457
return response.choices[0].message.content, response.usage.completion_tokens
5558

56-
# Create proxy client
57-
proxy_client = ProxyClient(
58-
config=config,
59-
fallback_client=client
60-
)
59+
# Create or reuse proxy client to maintain state (important for round-robin)
60+
config_key = str(config) # Simple config-based cache key
61+
if config_key not in _proxy_client_cache:
62+
logger.debug("Creating new proxy client instance")
63+
_proxy_client_cache[config_key] = ProxyClient(
64+
config=config,
65+
fallback_client=client
66+
)
67+
else:
68+
logger.debug("Reusing existing proxy client instance")
69+
70+
proxy_client = _proxy_client_cache[config_key]
6171

6272
# Check for wrapped approach in extra_body (recommended method)
6373
wrapped_approach = None

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ dependencies = [
4949
"mcp",
5050
"adaptive-classifier",
5151
"datasets",
52+
"PyYAML",
5253
"selenium",
5354
"webdriver-manager",
5455
# MLX support for Apple Silicon optimization

0 commit comments

Comments
 (0)