Differentiate custom from openrouter models
Split readme into multiple docs
This commit is contained in:
@@ -176,52 +176,50 @@ class CustomProvider(OpenAICompatibleProvider):
|
||||
"""
|
||||
logging.debug(f"Custom provider validating model: '{model_name}'")
|
||||
|
||||
# If OpenRouter is available and this looks like a cloud model, defer to OpenRouter
|
||||
openrouter_available = os.getenv("OPENROUTER_API_KEY") is not None
|
||||
|
||||
# Try to resolve through registry first
|
||||
config = self._registry.resolve(model_name)
|
||||
if config:
|
||||
model_id = config.model_name
|
||||
# Only accept models that are clearly local/custom based on the resolved name
|
||||
# Local models should not have vendor/ prefix (except for special cases)
|
||||
is_local_model = (
|
||||
"/" not in model_id # Simple names like "llama3.2"
|
||||
or "local" in model_id.lower() # Explicit local indicator
|
||||
or
|
||||
# Check if any of the aliases contain local indicators
|
||||
any("local" in alias.lower() or "ollama" in alias.lower() for alias in config.aliases)
|
||||
if hasattr(config, "aliases")
|
||||
else False
|
||||
)
|
||||
|
||||
if is_local_model:
|
||||
logging.debug(f"Model '{model_name}' -> '{model_id}' validated via registry (local model)")
|
||||
# Use explicit is_custom flag for clean validation
|
||||
if config.is_custom:
|
||||
logging.debug(f"Model '{model_name}' -> '{model_id}' validated via registry (custom model)")
|
||||
return True
|
||||
else:
|
||||
# This is a cloud/OpenRouter model - reject it for custom provider
|
||||
logging.debug(f"Model '{model_name}' -> '{model_id}' rejected (cloud model for OpenRouter)")
|
||||
# This is a cloud/OpenRouter model - if OpenRouter is available, defer to it
|
||||
if openrouter_available:
|
||||
logging.debug(f"Model '{model_name}' -> '{model_id}' deferred to OpenRouter (cloud model)")
|
||||
else:
|
||||
logging.debug(f"Model '{model_name}' -> '{model_id}' rejected (cloud model, no OpenRouter)")
|
||||
return False
|
||||
|
||||
# Strip :latest suffix and try validation again (it's just a version tag)
|
||||
# Handle version tags for unknown models (e.g., "my-model:latest")
|
||||
clean_model_name = model_name
|
||||
if model_name.endswith(":latest"):
|
||||
clean_model_name = model_name[:-7] # Remove ":latest"
|
||||
logging.debug(f"Stripped :latest from '{model_name}' -> '{clean_model_name}'")
|
||||
if ":" in model_name:
|
||||
clean_model_name = model_name.split(":")[0]
|
||||
logging.debug(f"Stripped version tag from '{model_name}' -> '{clean_model_name}'")
|
||||
# Try to resolve the clean name
|
||||
config = self._registry.resolve(clean_model_name)
|
||||
if config:
|
||||
return self.validate_model_name(clean_model_name) # Recursively validate clean name
|
||||
|
||||
# For unknown models (not in registry), only accept if they look like local models
|
||||
# This maintains backward compatibility for custom models not yet in the registry
|
||||
|
||||
# Accept models with explicit local indicators in the name
|
||||
if any(indicator in clean_model_name.lower() for indicator in ["local", "ollama", "vllm", "lmstudio"]):
|
||||
logging.debug(f"Model '{clean_model_name}' validated via local indicators")
|
||||
return True
|
||||
|
||||
# Accept simple model names without vendor prefix ONLY if they're not in registry
|
||||
# This allows for unknown local models like custom fine-tunes
|
||||
if "/" not in clean_model_name and ":" not in clean_model_name and not config:
|
||||
logging.debug(f"Model '{clean_model_name}' validated via simple name pattern (unknown local model)")
|
||||
# Accept simple model names without vendor prefix (likely local/custom models)
|
||||
if "/" not in clean_model_name:
|
||||
logging.debug(f"Model '{clean_model_name}' validated as potential local model (no vendor prefix)")
|
||||
return True
|
||||
|
||||
logging.debug(f"Model '{model_name}' NOT validated by custom provider")
|
||||
# Reject everything else (likely cloud models not in registry)
|
||||
logging.debug(f"Model '{model_name}' rejected by custom provider (appears to be cloud model)")
|
||||
return False
|
||||
|
||||
def generate_content(
|
||||
|
||||
@@ -75,11 +75,11 @@ class OpenAICompatibleProvider(ModelProvider):
|
||||
logging.info(f"Configured allowed models for {self.FRIENDLY_NAME}: {sorted(models)}")
|
||||
return models
|
||||
|
||||
# Log warning if no allow-list configured for proxy providers
|
||||
# Log info if no allow-list configured for proxy providers
|
||||
if self.get_provider_type() not in [ProviderType.GOOGLE, ProviderType.OPENAI]:
|
||||
logging.warning(
|
||||
f"No model allow-list configured for {self.FRIENDLY_NAME}. "
|
||||
f"Set {env_var} to restrict model access and control costs."
|
||||
logging.info(
|
||||
f"Model allow-list not configured for {self.FRIENDLY_NAME} - all models permitted. "
|
||||
f"To restrict access, set {env_var} with comma-separated model names."
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@@ -24,6 +24,7 @@ class OpenRouterModelConfig:
|
||||
supports_streaming: bool = True
|
||||
supports_function_calling: bool = False
|
||||
supports_json_mode: bool = False
|
||||
is_custom: bool = False # True for models that should only be used with custom endpoints
|
||||
description: str = ""
|
||||
|
||||
def to_capabilities(self) -> ModelCapabilities:
|
||||
|
||||
Reference in New Issue
Block a user