ellmer 0.3.0

  ai, ellmer

  Hadley Wickham

We’re thrilled to announce that ellmer 0.3.0 is now available on CRAN! ellmer is an R package designed to make it easy to use large language models (LLMs) from R. It supports a wide variety of providers (including OpenAI, Anthropic, Azure, Google, Snowflake, Databricks and many more), makes it easy to extract structured data, and to give the LLM the ability to call R functions via tool calling.

You can install the latest version from CRAN with:

install.packages("ellmer")

This release brings several exciting improvements: a simplified chat interface, enhanced tool specifications, and numerous quality of life improvements that make working with LLMs more reliable and efficient. Let’s dive into what’s new!

Simplified chat interface

The biggest new feature in this release is the chat() function, which provides an easy way to start a conversations with any provider. Instead of using different function names for different providers, you can now use a single string:

# You can specify a particular model
openai_chat <- chat("openai/gpt-4.1")
openai_chat$chat("Tell me a joke about an R programmer")
#> Why did the R programmer get kicked out of the party?
#> 
#> Because he kept trying to **arrange** everyone in **ascending order**!

# Or use the default for a given provider
anthropic_chat <- chat("anthropic")
#> Using model = "claude-sonnet-4-20250514".
anthropic_chat$chat("Write an acrostic for tidyr")
#> Here's an acrostic for tidyr:
#> 
#> **T**ransform messy data into structured form  
#> **I**ntegrate scattered pieces with ease  
#> **D**ata wrangling becomes the norm  
#> **Y**our datasets pivot and find their peace  
#> **R**eshaping chaos into organized dreams

Improved tool specification

We’ve significantly simplified how you define tools for function calling. The tool() function now has a cleaner, more intuitive specification that focuses on the essentials: the function, a name, a description, and the arguments specification.

get_weather <- tool(
  function(location, unit = "celsius") {
    # Function implementation here
    paste0("Weather in ", location, " is 22 ", unit)
  },
  name = "get_weather",
  description = "Get current weather for a location",
  arguments = list(
    location = type_string("The city and state, e.g. San Francisco, CA"),
    unit = type_enum(c("C", "F"), "Temperature unit: celsius/fahrenheit")
  )
)

# Use the tool in a chat
chat <- chat("anthropic")
#> Using model = "claude-sonnet-4-20250514".
chat$register_tool(get_weather)
chat$chat("What's the weather in Paris?")
#> The current weather in Paris, France is 22°C (about 72°F). It's quite pleasant 
#> weather!

This is a breaking change from previous versions, and I apologise for the pain that this will cause. However, I’m confident that this is a better interface overall and will make tool usage clearer and more maintainable in the long run. If you have existing tools you need to convert to the new format, check out ?tool for an LLM prompt to help you automate the work.

We’ve also tweaked the type specification functions: type_array() and type_enum(). These now have a more logical argument order, with the values/items first and the description second:

type_colour <- type_enum(c("red", "green", "blue"), "Colour options")
type_names <- type_array(type_string())

This makes them a little easier to use since values and items are required and the description is optional.

Quality of life improvements

This release includes several improvements that make ellmer more reliable and easier to use at scale:

  • Enhanced reliability. ellmer now retries requests up to 3 times by default (controllable with options(ellmer_max_tries)), and will retry if the connection fails, not just if the request returns a transient error. The default timeout (options(ellmer_timeout_s)) now applies to the initial connection phase. Together these changes should make ellmer much more reliable in turbulent network conditions.

  • Batch processing. New parallel_chat_text() and batch_chat_text() functions make it easy to just extract the text responses from parallel/batch responses.

  • Better cost tracking. ellmer’s cost estimates are now more accurate and comprehensive. chat_openai() and chat_google_gemini() now distinguish between cached and uncached input tokens. And we’ve switched to LiteLLM as our pricing data source, dramatically expanding the number of providers and models with cost information.

Acknowledgements

We’re grateful to all the contributors who made this release possible through their code contributions, bug reports, and feedback. Your input helps make ellmer better for the entire R community working with large language models! @acastroaraujo, @arcenis-r, @arnavchauhan7, @arunrajes, @atheriel, @benyake, @bgreenwell, @bianchenhao, @blairj09, @brynhum, @bshor, @bvhest, @claytonperry, @CorradoLanera, @cpsievert, @diegoperoni, @elnelson575, @frankcsliu, @gadenbuie, @gbiele, @hadley, @hafen, @howardbaik, @Ifeanyi55, @IL04, @joshyam-k, @JsizzleR, @jvandens, @kchou496, @lepromatous, @mattwarkentin, @michalovadek, @moodymudskipper, @netique, @paddytobias, @pietervreeburg, @polinah7, @rkrug, @rpodcast, @Sade154, @salim-b, @simonpcouch, @smach, @SokolovAnatoliy, @stefanlinner, @thisisnic, and @vorpalvorpal.