R/get_provider.R

Defines functions get_provider

Documented in get_provider

#' Determine provider from model name
#'
#' This function determines the appropriate provider (e.g., OpenAI, Anthropic, Google, OpenRouter) based on the model name.
#' Uses prefix-based matching for efficient and maintainable provider detection.
#' New models following existing naming conventions are automatically supported.
#'
#' @param model Character string specifying the model name (e.g., "gpt-5.5", "claude-opus-4-7").
#' @return Character string of the provider name (e.g., "openai", "anthropic").
#' @details
#' Supported providers and model prefixes:
#' \itemize{
#'   \item OpenAI: gpt-*, o1*, o3*, o4*, chatgpt-*, codex-* (e.g., 'gpt-5.5', 'gpt-5.4-mini')
#'   \item Anthropic: claude-* (e.g., 'claude-opus-4-7', 'claude-sonnet-4-6')
#'   \item DeepSeek: deepseek-* (e.g., 'deepseek-v4-flash', 'deepseek-v4-pro')
#'   \item Google: gemini-* (e.g., 'gemini-3.1-pro-preview', 'gemini-3-flash-preview')
#'   \item Qwen: qwen*, qwq-* (e.g., 'qwen3.6-plus', 'qwen3.6-flash')
#'   \item Stepfun: step-* (e.g., 'step-3.5-flash', 'step-3')
#'   \item Zhipu: glm-*, chatglm* (e.g., 'glm-5.1', 'glm-5-turbo')
#'   \item MiniMax: minimax-* (e.g., 'MiniMax-M2.7', 'MiniMax-M2.5')
#'   \item Grok: grok-* (e.g., 'grok-4.3', 'grok-4.3-latest')
#'   \item OpenRouter: Any model with '/' in the name (e.g., 'openai/gpt-5.5', 'anthropic/claude-opus-4.7')
#' }
#' @export
get_provider <- function(model) {
  if (!is.character(model) || length(model) != 1 || is.na(model) || !nzchar(trimws(model))) {
    stop("model must be a non-empty character scalar")
  }

  # Normalize model name to lowercase for case-insensitive matching
  model_lower <- tolower(model)

  # OpenRouter models always contain '/' (e.g., 'openai/gpt-5.5')
  if (grepl("/", model_lower)) {
    return("openrouter")
  }

  # Check for custom models
  if (exists(model_lower, envir = custom_models)) {
    model_data <- get(model_lower, envir = custom_models)
    return(model_data$provider)
  }

  # Prefix-based provider detection
  # Each regex matches the naming convention of a provider's models
  provider_patterns <- list(
    "openai"    = "^(gpt-|o[0-9]|chatgpt-|codex-)",
    "anthropic" = "^claude-",
    "deepseek"  = "^deepseek-",
    "gemini"    = "^gemini-",
    "qwen"      = "^(qwen|qwq-)",
    "stepfun"   = "^step-",
    "zhipu"     = "^(glm-|chatglm)",
    "minimax"   = "^minimax-",
    "grok"      = "^grok-"
  )

  for (provider in names(provider_patterns)) {
    if (grepl(provider_patterns[[provider]], model_lower)) {
      return(provider)
    }
  }

  # No match — report error with supported prefixes
  supported <- paste(
    vapply(names(provider_patterns), function(p) {
      sprintf("  %s: %s", p, provider_patterns[[p]])
    }, character(1)),
    collapse = "\n"
  )
  stop(
    "Cannot determine provider for model: '", model, "'\n",
    "Supported model name patterns:\n", supported, "\n",
    "  openrouter: any model containing '/'\n",
    "Tip: Check for typos in the model name."
  )
}

Try the mLLMCelltype package in your browser

Any scripts or data that you put into this service are public.

mLLMCelltype documentation built on May 11, 2026, 9:06 a.m.