Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions aisuite/providers/uncommonroute_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import os
import httpx
from aisuite.provider import Provider, LLMError
from aisuite.providers.message_converter import OpenAICompliantMessageConverter


class UncommonrouteProvider(Provider):
"""
UncommonRoute provider - an intelligent LLM cost optimizer.

UncommonRoute runs as a local proxy that analyzes each request and
routes it to the most cost-effective model capable of handling the task.

Setup:
pipx install uncommon-route
uncommon-route init
uncommon-route serve

Configuration:
Set UNCOMMON_ROUTE_BASE_URL (default: http://localhost:8403/v1)
Or pass base_url in provider config.

Usage:
client = ai.Client()
response = client.chat.completions.create(
model="uncommonroute:auto",
messages=[{"role": "user", "content": "Hello!"}],
)

Routing modes (passed as the model name):
- auto: balanced quality-per-dollar (recommended)
- fast: cost-first, routes to cheapest capable model
- best: quality-first, uses strongest model available

Learn more: https://github.com/CommonstackAI/UncommonRoute
"""

BASE_URL = "http://localhost:8403/v1"

def __init__(self, **config):
self.base_url = config.get(
"base_url",
os.getenv("UNCOMMON_ROUTE_BASE_URL", self.BASE_URL),
)
self.timeout = config.get("timeout", 60)
self.converter = OpenAICompliantMessageConverter()

def chat_completions_create(self, model, messages, **kwargs):
model = self._resolve_model(model)
converted_messages = self.converter.convert_request(messages)

data = {
"model": model,
"messages": converted_messages,
**kwargs,
}

url = self.base_url.rstrip("/") + "/chat/completions"

try:
response = httpx.post(url, json=data, timeout=self.timeout)
response.raise_for_status()
except httpx.ConnectError:
raise LLMError(
"Could not connect to UncommonRoute. "
"Make sure it is running: uncommon-route serve"
)
except httpx.HTTPStatusError as e:
raise LLMError(f"UncommonRoute request failed: {e}")
except Exception as e:
raise LLMError(f"An error occurred: {e}")

return self.converter.convert_response(response.json())

def _resolve_model(self, model):
mode_map = {
"auto": "uncommon-route/auto",
"fast": "uncommon-route/fast",
"best": "uncommon-route/best",
}
return mode_map.get(model, model)
67 changes: 67 additions & 0 deletions tests/providers/test_uncommonroute_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import unittest
from unittest.mock import patch, MagicMock
from aisuite.providers.uncommonroute_provider import UncommonrouteProvider


class TestUncommonrouteProvider(unittest.TestCase):
def setUp(self):
self.provider = UncommonrouteProvider()

def test_default_base_url(self):
self.assertEqual(self.provider.base_url, "http://localhost:8403/v1")

def test_custom_base_url(self):
provider = UncommonrouteProvider(base_url="http://myhost:9000/v1")
self.assertEqual(provider.base_url, "http://myhost:9000/v1")

def test_resolve_model_auto(self):
self.assertEqual(self.provider._resolve_model("auto"), "uncommon-route/auto")

def test_resolve_model_fast(self):
self.assertEqual(self.provider._resolve_model("fast"), "uncommon-route/fast")

def test_resolve_model_best(self):
self.assertEqual(self.provider._resolve_model("best"), "uncommon-route/best")

def test_resolve_model_passthrough(self):
self.assertEqual(self.provider._resolve_model("gpt-4o"), "gpt-4o")

@patch("aisuite.providers.uncommonroute_provider.httpx.post")
def test_chat_completions_create(self, mock_post):
mock_response = MagicMock()
mock_response.json.return_value = {
"choices": [
{
"message": {"role": "assistant", "content": "Hello!"},
"finish_reason": "stop",
}
]
}
mock_response.raise_for_status = MagicMock()
mock_post.return_value = mock_response

messages = [{"role": "user", "content": "Hi"}]
result = self.provider.chat_completions_create("auto", messages)

self.assertEqual(result.choices[0].message.content, "Hello!")

call_args = mock_post.call_args
self.assertIn("/chat/completions", call_args[0][0])
self.assertEqual(call_args[1]["json"]["model"], "uncommon-route/auto")

@patch("aisuite.providers.uncommonroute_provider.httpx.post")
def test_connect_error(self, mock_post):
from aisuite.provider import LLMError
import httpx

mock_post.side_effect = httpx.ConnectError("refused")

with self.assertRaises(LLMError) as ctx:
self.provider.chat_completions_create(
"auto", [{"role": "user", "content": "Hi"}]
)
self.assertIn("uncommon-route serve", str(ctx.exception))


if __name__ == "__main__":
unittest.main()