From 303f7f49e8a40763f222f670e6cd7f9b3e8e40df Mon Sep 17 00:00:00 2001 From: jcrodriguez1989 Date: Thu, 22 Jan 2026 08:51:59 -0300 Subject: [PATCH 1/2] Feature: Add models_deepseek() --- NAMESPACE | 1 + R/provider-deepseek.R | 34 +++++++++++++++++++++++++ man/chat_deepseek.Rd | 7 +++++ tests/testthat/test-provider-deepseek.R | 4 +++ 4 files changed, 46 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 5a3e24abe..c1658ca7e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -86,6 +86,7 @@ export(live_console) export(models_anthropic) export(models_aws_bedrock) export(models_claude) +export(models_deepseek) export(models_github) export(models_google_gemini) export(models_google_vertex) diff --git a/R/provider-deepseek.R b/R/provider-deepseek.R index f97eb37a6..6f54ef8d6 100644 --- a/R/provider-deepseek.R +++ b/R/provider-deepseek.R @@ -127,3 +127,37 @@ method(as_json, list(ProviderDeepSeek, Turn)) <- function(provider, x, ...) { } deepseek_key <- function() key_get("DEEPSEEK_API_KEY") + +#' @export +#' @rdname chat_deepseek +models_deepseek <- function( + base_url = "https://api.deepseek.com", + api_key = NULL, + credentials = NULL +) { + credentials <- as_credentials( + "models_deepseek", + \() deepseek_key(), + credentials = credentials, + api_key = api_key + ) + + provider <- ProviderDeepSeek( + name = "DeepSeek", + model = "", + base_url = base_url, + credentials = credentials + ) + + req <- base_request(provider) + req <- req_url_path_append(req, "/models") + resp <- req_perform(req) + + json <- resp_body_json(resp) + + id <- map_chr(json$data, "[[", "id") + owned_by <- map_chr(json$data, "[[", "owned_by") + + df <- data.frame(id = id, owned_by = owned_by) + cbind(df, match_prices(provider@name, df$id)) +} diff --git a/man/chat_deepseek.Rd b/man/chat_deepseek.Rd index a2965b7a3..7deaace26 100644 --- a/man/chat_deepseek.Rd +++ b/man/chat_deepseek.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/provider-deepseek.R \name{chat_deepseek} \alias{chat_deepseek} +\alias{models_deepseek} \title{Chat with a model hosted on DeepSeek} \usage{ chat_deepseek( @@ -15,6 +16,12 @@ chat_deepseek( echo = NULL, api_headers = character() ) + +models_deepseek( + base_url = "https://api.deepseek.com", + api_key = NULL, + credentials = NULL +) } \arguments{ \item{system_prompt}{A system prompt to set the behavior of the assistant.} diff --git a/tests/testthat/test-provider-deepseek.R b/tests/testthat/test-provider-deepseek.R index 97bddc734..28f349c62 100644 --- a/tests/testthat/test-provider-deepseek.R +++ b/tests/testthat/test-provider-deepseek.R @@ -13,6 +13,10 @@ test_that("can make simple streaming request", { expect_match(paste0(unlist(resp), collapse = ""), "2") }) +test_that("can list models", { + test_models(models_deepseek) +}) + # Common provider interface ----------------------------------------------- test_that("defaults are reported", { From c9fe1634836398d8568b7de7b9d588b4e7eb1559 Mon Sep 17 00:00:00 2001 From: jcrodriguez1989 Date: Thu, 22 Jan 2026 10:46:08 -0300 Subject: [PATCH 2/2] Updating NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index f6e5e582a..57905cf15 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ * ellmer will now distinguish text content from thinking content while streaming, allowing downstream packages like shinychat to provide specific UI for thinking content (@simonpcouch, #909). * `chat_github()` now uses `chat_openai_compatible()` for improved compatibility, and `models_github()` now supports custom `base_url` configuration (@D-M4rk, #877). * `chat_ollama()` now contains a slot for `top_k` within the `params` argument (@frankiethull). +* `models_deepseek()` lists available models for `chat_deepseek()` (@jcrodriguez1989, #919). # ellmer 0.4.0