-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
Fixes #242
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#' @include provider-openai.R | ||
NULL | ||
|
||
#' Chat with a model hosted on DeepSeek | ||
#' | ||
#' @description | ||
#' Sign up at <https://platform.deepseek.com>. | ||
#' | ||
#' This function is a lightweight wrapper around [chat_openai()] with | ||
#' default settings tailored for DeepSeek. | ||
#' | ||
#' ## Known limitations | ||
#' | ||
#' * Structured data extraction is not supported.. | ||
#' * Function calling is currently [unstable](https://api-docs.deepseek.com/guides/function_calling). | ||
#' * Images are not supported. | ||
#' | ||
#' @export | ||
#' @family chatbots | ||
#' @inheritParams chat_openai | ||
#' @inherit chat_openai return | ||
#' @examples | ||
#' \dontrun{ | ||
#' chat <- chat_deepseek() | ||
#' chat$chat("Tell me three jokes about statisticians") | ||
#' } | ||
chat_deepseek <- function(system_prompt = NULL, | ||
turns = NULL, | ||
api_key = deepseek_key(), | ||
model = NULL, | ||
seed = NULL, | ||
api_args = list(), | ||
echo = NULL) { | ||
|
||
turns <- normalize_turns(turns, system_prompt) | ||
model <- set_default(model, "deepseek-chat") | ||
echo <- check_echo(echo) | ||
|
||
if (is_testing() && is.null(seed)) { | ||
seed <- seed %||% 1014 | ||
} | ||
|
||
provider <- ProviderDeepSeek( | ||
base_url = "https://api.deepseek.com", | ||
model = model, | ||
seed = seed, | ||
extra_args = api_args, | ||
api_key = api_key | ||
) | ||
Chat$new(provider = provider, turns = turns, echo = echo) | ||
} | ||
|
||
ProviderDeepSeek <- new_class("ProviderDeepSeek", parent = ProviderOpenAI) | ||
|
||
method(as_json, list(ProviderDeepSeek, ContentText)) <- function(provider, x) { | ||
x@text | ||
} | ||
|
||
method(as_json, list(ProviderDeepSeek, Turn)) <- function(provider, x) { | ||
if (x@role == "user") { | ||
# Text and tool results go in separate messages | ||
texts <- keep(x@contents, S7_inherits, ContentText) | ||
texts_out <- lapply(texts, function(text) { | ||
list(role = "user", content = as_json(provider, text)) | ||
}) | ||
|
||
tools <- keep(x@contents, S7_inherits, ContentToolResult) | ||
tools_out <- lapply(tools, function(tool) { | ||
list(role = "tool", content = tool_string(tool), tool_call_id = tool@id) | ||
}) | ||
|
||
c(texts_out, tools_out) | ||
} else if (x@role == "assistant") { | ||
# Tool requests come out of content and go into own argument | ||
text <- detect(x@contents, S7_inherits, ContentText) | ||
tools <- keep(x@contents, S7_inherits, ContentToolRequest) | ||
|
||
list(compact(list( | ||
role = "assistant", | ||
content = as_json(provider, text), | ||
tool_calls = as_json(provider, tools) | ||
))) | ||
} else { | ||
as_json(super(provider, ProviderOpenAI), x) | ||
} | ||
} | ||
|
||
deepseek_key <- function() key_get("DEEPSEEK_API_KEY") |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# defaults are reported | ||
|
||
Code | ||
. <- chat_deepseek() | ||
Message | ||
Using model = "deepseek-chat". | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Getting started -------------------------------------------------------- | ||
|
||
test_that("can make simple request", { | ||
chat <- chat_deepseek("Be as terse as possible; no punctuation") | ||
resp <- chat$chat("What is 1 + 1?", echo = FALSE) | ||
expect_match(resp, "2") | ||
expect_equal(chat$last_turn()@tokens, c(20, 1)) | ||
}) | ||
|
||
test_that("can make simple streaming request", { | ||
chat <- chat_deepseek("Be as terse as possible; no punctuation") | ||
resp <- coro::collect(chat$stream("What is 1 + 1?")) | ||
expect_match(paste0(unlist(resp), collapse = ""), "2") | ||
}) | ||
|
||
# Common provider interface ----------------------------------------------- | ||
|
||
test_that("defaults are reported", { | ||
expect_snapshot(. <- chat_deepseek()) | ||
}) | ||
|
||
test_that("respects turns interface", { | ||
chat_fun <- chat_deepseek | ||
|
||
test_turns_system(chat_fun) | ||
test_turns_existing(chat_fun) | ||
}) | ||
|
||
# Only partially works | ||
# test_that("all tool variations work", { | ||
# chat_fun <- chat_deepseek | ||
|
||
# test_tools_simple(chat_fun) | ||
# test_tools_async(chat_fun) | ||
# test_tools_parallel(chat_fun) | ||
# test_tools_sequential(chat_fun, total_calls = 6) | ||
# }) | ||
|
||
# # Doesn't support data extraction | ||
# test_that("can extract data", { | ||
# chat_fun <- chat_deepseek | ||
|
||
# test_data_extraction(chat_fun) | ||
# }) | ||
|
||
# # Doesn't support images | ||
# test_that("can use images", { | ||
# chat_fun <- chat_deepseek_test | ||
|
||
# test_images_inline(chat_fun) | ||
# test_images_remote(chat_fun) | ||
# }) |