File size: 5,050 Bytes
37eaf2d
 
08305d0
129df6c
e3952f9
37eaf2d
4a5b501
 
37eaf2d
4a5b501
 
 
 
 
08305d0
 
129df6c
4a5b501
 
129df6c
 
e3952f9
129df6c
 
e3952f9
 
 
 
 
 
4a5b501
 
 
e3952f9
 
129df6c
37eaf2d
4a5b501
37eaf2d
4a5b501
08305d0
 
4a5b501
 
08305d0
 
 
4a5b501
08305d0
4a5b501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08305d0
 
37eaf2d
 
 
 
 
4a5b501
37eaf2d
 
 
 
 
 
 
 
 
 
 
 
 
4a5b501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import os
from typing import Any, Callable
from functools import lru_cache
import time
import re

from smolagents import LiteLLMModel
from litellm import RateLimitError

# IMPORTANT: Set these environment variables BEFORE importing/using litellm
# This tells LiteLLM to route through OpenRouter
"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"
os.environ["OPENROUTER_API_KEY"] = os.getenv("OPENROUTER_API_KEY", )
os.environ["OPENROUTER_API_BASE"] = "https://openrouter.ai/api/v1"


class WrapperLiteLLMModel(LiteLLMModel):
    """Wrapper for LiteLLMModel with retry logic for rate limits."""
    
    def __call__(self, messages, **kwargs):
        max_retry = 5
        for attempt in range(max_retry):
            try:
                return super().__call__(messages, **kwargs)
            except RateLimitError as e:
                print(f"RateLimitError (attempt {attempt+1}/{max_retry})")
                match = re.search(r'"retryDelay": ?"(\d+)s"', str(e))
                retry_seconds = int(match.group(1)) if match else 50
                print(f"Sleeping for {retry_seconds} seconds before retrying...")
                time.sleep(retry_seconds)
            except Exception as e:
                print(f"Error: {type(e).__name__}: {e}")
                raise

        raise RateLimitError(f"Rate limit exceeded after {max_retry} retries.")


def get_lite_llm_model(model_id: str, **kwargs) -> WrapperLiteLLMModel:
    """
    Returns a LiteLLM model instance configured for OpenRouter.

    Args:
        model_id (str): The model identifier in OpenRouter format.
                       Example: "openrouter/google/gemini-2.0-flash-001"
        **kwargs: Additional keyword arguments for the model.

    Returns:
        WrapperLiteLLMModel: LiteLLM model instance.
    """
    api_key = os.getenv("OPENROUTER_API_KEY", "")
    
    if not api_key:
        raise ValueError(
            "OPENROUTER_API_KEY environment variable is not set. "
            "Please set it with: export OPENROUTER_API_KEY='your-key-here'"
        )
    
    # Ensure the model_id starts with "openrouter/"
    if not model_id.startswith("openrouter/"):
        print(f"Warning: model_id should start with 'openrouter/'. Got: {model_id}")
        print(f"Prepending 'openrouter/' to model_id")
        model_id = f"openrouter/{model_id}"
    
    print(f"Initializing LiteLLM model: {model_id}")
    
    return WrapperLiteLLMModel(
        model_id=model_id,
        api_key=api_key,
        # Don't set api_base here - let litellm handle it via OPENROUTER_API_BASE env var
        **kwargs
    )


def get_model(model_type: str, model_id: str, **kwargs) -> Any:
    """
    Returns a model instance based on the specified type.

    Args:
        model_type (str): The type of the model ("LiteLLMModel").
        model_id (str): The model identifier.
        **kwargs: Additional keyword arguments for the model.

    Returns:
        Any: Model instance of the specified type.
    """
    models: dict[str, Callable[..., Any]] = {
        "LiteLLMModel": get_lite_llm_model,
    }

    if model_type not in models:
        raise ValueError(f"Unknown model type: {model_type}")

    return models[model_type](model_id, **kwargs)


# ============================================================================
# AVAILABLE OPENROUTER MODELS (as of 2025)
# ============================================================================
# Format: "openrouter/<provider>/<model-name>"
#
# FREE MODELS (good for testing):
#   - openrouter/google/gemini-2.0-flash-001
#   - openrouter/meta-llama/llama-3.2-3b-instruct:free
#   - openrouter/microsoft/phi-3-mini-128k-instruct:free
#   - openrouter/qwen/qwen-2-7b-instruct:free
#
# PAID MODELS (better quality):
#   - openrouter/anthropic/claude-3.5-sonnet
#   - openrouter/anthropic/claude-3-haiku
#   - openrouter/openai/gpt-4o-mini
#   - openrouter/openai/gpt-4o
#   - openrouter/google/gemini-pro
#   - openrouter/google/gemini-1.5-flash
#   - openrouter/meta-llama/llama-3.1-70b-instruct
#   - openrouter/mistralai/mistral-large
#
# Check https://openrouter.ai/models for the full list and current availability
# ============================================================================


if __name__ == "__main__":
    # Test the model
    print("Testing OpenRouter connection...")
    
    try:
        # Use a free model for testing
        model = get_model("LiteLLMModel", "openrouter/google/gemini-2.0-flash-001")
        
        # Simple test
        messages = [{"role": "user", "content": "Say hello in one word."}]
        response = model(messages)
        print(f"Response: {response}")
        print("✅ OpenRouter connection successful!")
        
    except Exception as e:
        print(f"❌ Error: {type(e).__name__}: {e}")
        print("\nTroubleshooting:")
        print("1. Make sure OPENROUTER_API_KEY is set")
        print("2. Check your API key at https://openrouter.ai/keys")
        print("3. Verify you have credits at https://openrouter.ai/credits")