ReqLLM (ReqLLM v1.0.0-rc.5)

View Source

Main API facade for Req AI.

Inspired by the Vercel AI SDK, provides a unified interface to AI providers with flexible model specifications, rich prompt support, configuration management, and structured data generation.

Quick Start

# Simple text generation using string format
ReqLLM.generate_text("anthropic:claude-3-5-sonnet", "Hello world")
#=> {:ok, "Hello! How can I assist you today?"}

# Structured data generation with schema validation
schema = [
  name: [type: :string, required: true],
  age: [type: :pos_integer, required: true]
]
ReqLLM.generate_object("anthropic:claude-3-5-sonnet", "Generate a person", schema)
#=> {:ok, %{name: "John Doe", age: 30}}

Model Specifications

Multiple formats supported for maximum flexibility:

# String format: "provider:model"
ReqLLM.generate_text("anthropic:claude-3-5-sonnet-20241022", messages)

# Tuple format: {provider, options}
ReqLLM.generate_text({:anthropic, "claude-3-5-sonnet", temperature: 0.7}, messages)

# Model struct format
model = %ReqLLM.Model{provider: :anthropic, model: "claude-3-5-sonnet", temperature: 0.5}
ReqLLM.generate_text(model, messages)

Configuration

ReqLLM uses the JidoKeys keyring for API key storage:

# Store API keys in session keyring
ReqLLM.put_key(:anthropic_api_key, "sk-ant-...")
ReqLLM.put_key(:openai_api_key, "sk-...")

# Retrieve API keys
ReqLLM.get_key(:anthropic_api_key)

Providers

Built-in support for major AI providers:

  • Anthropic: Claude 3.5 Sonnet, Claude 3 Haiku, Claude 3 Opus

    # Access provider modules directly provider = ReqLLM.provider(:anthropic) provider.generate_text(model, messages, opts)

Summary

Functions

Get all supported capabilities for a model.

Creates a context from a list of messages, a single message struct, or a string.

Calculates cosine similarity between two embedding vectors.

Generates embeddings for single or multiple text inputs.

Generates structured data using an AI model with schema validation.

Generates structured data using an AI model, returning only the object content.

Generates text using an AI model with full response metadata.

Generates text using an AI model, returning only the text content.

Gets an API key from the keyring.

Creates a JSON schema object compatible with ReqLLM.

Creates a model struct from various specifications.

Gets a provider module from the registry.

Stores an API key in the session keyring.

Streams structured data generation using an AI model with schema validation.

DEPRECATED: This function will be removed in a future version.

Streams text generation using an AI model with concurrent metadata collection.

DEPRECATED: This function will be removed in a future version.

Creates a Tool struct for AI model function calling.

Functions

capabilities(model_spec)

Get all supported capabilities for a model.

Returns a list of capability atoms that the model supports based on provider metadata.

Parameters

  • model_spec - Model specification in various formats

Examples

ReqLLM.capabilities("anthropic:claude-3-haiku")
#=> [:max_tokens, :system_prompt, :temperature, :tools, :streaming]

model = %ReqLLM.Model{provider: :anthropic, model: "claude-3-sonnet"}
ReqLLM.capabilities(model)
#=> [:max_tokens, :system_prompt, :temperature, :tools, :streaming, :reasoning]

context(message_list)

@spec context([struct()] | struct() | String.t()) :: ReqLLM.Context.t()

Creates a context from a list of messages, a single message struct, or a string.

Parameters

  • messages - List of Message structs, a single Message struct, or a string

Examples

messages = [
  ReqLLM.Context.system("You are helpful"),
  ReqLLM.Context.user("Hello!")
]
ctx = ReqLLM.context(messages)
# Now you can use Enum functions on the context
user_msgs = ctx |> Enum.filter(&(&1.role == :user))

# Single message struct
ctx = ReqLLM.context(ReqLLM.Context.user("Hello!"))

# String prompt
ctx = ReqLLM.context("Hello!")

cosine_similarity(embedding_a, embedding_b)

@spec cosine_similarity([number()], [number()]) :: float()

Calculates cosine similarity between two embedding vectors.

Equivalent to Vercel AI SDK's cosineSimilarity() function. Returns a similarity score between -1 and 1, where:

  • 1.0 indicates identical vectors (maximum similarity)
  • 0.0 indicates orthogonal vectors (no similarity)
  • -1.0 indicates opposite vectors (maximum dissimilarity)

Parameters

  • embedding_a - First embedding vector (list of numbers)
  • embedding_b - Second embedding vector (list of numbers)

Examples

# Identical vectors
ReqLLM.cosine_similarity([1.0, 0.0, 0.0], [1.0, 0.0, 0.0])
#=> 1.0

# Orthogonal vectors
ReqLLM.cosine_similarity([1.0, 0.0], [0.0, 1.0])
#=> 0.0

# Opposite vectors
ReqLLM.cosine_similarity([1.0, 0.0], [-1.0, 0.0])
#=> -1.0

# Similar vectors
ReqLLM.cosine_similarity([0.5, 0.8, 0.3], [0.6, 0.7, 0.4])
#=> 0.9487...

embed(model_spec, input, opts \\ [])

Generates embeddings for single or multiple text inputs.

Accepts either a single string or a list of strings, automatically handling both cases using pattern matching.

Parameters

  • model_spec - Model specification in various formats
  • input - Text string or list of text strings to generate embeddings for
  • opts - Additional options (keyword list)

Options

  • :dimensions - Number of dimensions for embeddings
  • :provider_options - Provider-specific options

Examples

# Single text input
{:ok, embedding} = ReqLLM.embed("openai:text-embedding-3-small", "Hello world")
#=> {:ok, [0.1, -0.2, 0.3, ...]}

# Multiple text inputs
{:ok, embeddings} = ReqLLM.embed(
  "openai:text-embedding-3-small",
  ["Hello", "World"]
)
#=> {:ok, [[0.1, -0.2, ...], [0.3, 0.4, ...]]}

generate_object(model_spec, messages, schema, opts \\ [])

Generates structured data using an AI model with schema validation.

Equivalent to Vercel AI SDK's generateObject() function, this method generates structured data according to a provided schema and validates the output against that schema.

Parameters

  • model_spec - Model specification in various formats
  • messages - Text prompt or list of messages
  • schema - Schema definition for structured output
  • opts - Additional options (keyword list)

Options

  • :output - Output type: :object, :array, :enum, or :no_schema
  • :mode - Generation mode: :auto, :json, or :tool
  • :schema_name - Optional name for the schema
  • :schema_description - Optional description for the schema
  • :enum - List of possible values (for enum output)
  • :temperature - Control randomness in responses (0.0 to 2.0)
  • :max_tokens - Limit the length of the response
  • :provider_options - Provider-specific options

Examples

# Generate a structured object
schema = [
  name: [type: :string, required: true],
  age: [type: :pos_integer, required: true]
]
{:ok, object} = ReqLLM.generate_object("anthropic:claude-3-sonnet", "Generate a person", schema)
#=> {:ok, %{name: "John Doe", age: 30}}

# Generate an array of objects
{:ok, objects} = ReqLLM.generate_object(
  "anthropic:claude-3-sonnet",
  "Generate 3 heroes",
  schema,
  output: :array
)

generate_object!(model_spec, messages, schema, opts \\ [])

Generates structured data using an AI model, returning only the object content.

This is a convenience function that extracts just the object from the response. For access to usage metadata and other response data, use generate_object/4.

Parameters

Same as generate_object/4.

Examples

ReqLLM.generate_object!("anthropic:claude-3-sonnet", "Generate a person", schema)
#=> %{name: "John Doe", age: 30}

generate_text(model_spec, messages, opts \\ [])

Generates text using an AI model with full response metadata.

Returns a canonical ReqLLM.Response which includes usage data, context, and metadata. For simple text-only results, use generate_text!/3.

Parameters

  • model_spec - Model specification in various formats
  • messages - Text prompt or list of messages
  • opts - Additional options (keyword list)

Options

  • :temperature - Control randomness in responses (0.0 to 2.0)
  • :max_tokens - Limit the length of the response
  • :top_p - Nucleus sampling parameter
  • :presence_penalty - Penalize new tokens based on presence
  • :frequency_penalty - Penalize new tokens based on frequency
  • :tools - List of tool definitions
  • :tool_choice - Tool choice strategy
  • :system_prompt - System prompt to prepend
  • :provider_options - Provider-specific options

Examples

{:ok, response} = ReqLLM.generate_text("anthropic:claude-3-sonnet", "Hello world")
ReqLLM.Response.text(response)
#=> "Hello! How can I assist you today?"

# Access usage metadata
ReqLLM.Response.usage(response)
#=> %{input_tokens: 10, output_tokens: 8}

generate_text!(model_spec, messages, opts \\ [])

Generates text using an AI model, returning only the text content.

This is a convenience function that extracts just the text from the response. For access to usage metadata and other response data, use generate_text/3. Raises on error.

Parameters

Same as generate_text/3.

Examples

ReqLLM.generate_text!("anthropic:claude-3-sonnet", "Hello world")
#=> "Hello! How can I assist you today?"

get_key(key)

@spec get_key(atom() | String.t()) :: String.t() | nil

Gets an API key from the keyring.

Keys from .env files are automatically loaded via JidoKeys+Dotenvy integration.

Parameters

  • key - The configuration key (atom or string, case-insensitive)

Examples

ReqLLM.get_key(:anthropic_api_key)
ReqLLM.get_key("ANTHROPIC_API_KEY")  # Auto-loaded from .env

json_schema(schema, opts \\ [])

@spec json_schema(keyword(), keyword()) :: map()

Creates a JSON schema object compatible with ReqLLM.

Equivalent to Vercel AI SDK's jsonSchema() helper, this function creates schema objects for structured data generation and validation.

Parameters

  • schema - NimbleOptions schema definition (keyword list)
  • opts - Additional options (optional)

Options

  • :validate - Custom validation function (optional)

Examples

# Basic schema
schema = ReqLLM.json_schema([
  name: [type: :string, required: true, doc: "User name"],
  age: [type: :integer, doc: "User age"]
])

# Schema with custom validation
schema = ReqLLM.json_schema(
  [email: [type: :string, required: true]],
  validate: fn value ->
    if String.contains?(value["email"], "@") do
      {:ok, value}
    else
      {:error, "Invalid email format"}
    end
  end
)

model(model_spec)

@spec model(String.t() | {atom(), keyword()} | struct()) ::
  {:ok, struct()} | {:error, term()}

Creates a model struct from various specifications.

Parameters

  • model_spec - Model specification in various formats:
    • String format: "anthropic:claude-3-sonnet"
    • Tuple format: {:anthropic, "claude-3-sonnet", temperature: 0.7}
    • Model struct: %ReqLLM.Model{}

Examples

ReqLLM.model("anthropic:claude-3-sonnet")
#=> {:ok, %ReqLLM.Model{provider: :anthropic, model: "claude-3-sonnet"}}

ReqLLM.model({:anthropic, "claude-3-sonnet", temperature: 0.5})
#=> {:ok, %ReqLLM.Model{provider: :anthropic, model: "claude-3-sonnet", temperature: 0.5}}

provider(provider)

@spec provider(atom()) :: {:ok, module()} | {:error, :not_found}

Gets a provider module from the registry.

Parameters

  • provider - Provider identifier (atom)

Examples

ReqLLM.provider(:anthropic)
#=> {:ok, ReqLLM.Providers.Anthropic}

ReqLLM.provider(:unknown)
#=> {:error, :not_found}

put_key(key, value)

@spec put_key(atom() | String.t(), term()) :: :ok

Stores an API key in the session keyring.

Keys from .env files are automatically loaded via JidoKeys+Dotenvy integration, so you typically don't need to call this manually. Just add keys to your .env file.

Parameters

  • key - The configuration key (atom or string)
  • value - The value to store

Examples

# Manual key setting (optional - .env keys are auto-loaded)
ReqLLM.put_key(:anthropic_api_key, "sk-ant-...")

stream_object(model_spec, messages, schema, opts \\ [])

Streams structured data generation using an AI model with schema validation.

Equivalent to Vercel AI SDK's streamObject() function, this method streams structured data generation according to a provided schema.

Parameters

  • model_spec - Model specification in various formats
  • messages - Text prompt or list of messages
  • schema - Schema definition for structured output
  • opts - Additional options (keyword list)

Options

Same as generate_object/4.

Examples

# Stream structured object generation
schema = [
  name: [type: :string, required: true],
  description: [type: :string, required: true]
]
{:ok, stream} = ReqLLM.stream_object("anthropic:claude-3-sonnet", "Generate a character", schema)
stream |> Enum.each(&IO.inspect/1)

stream_object!(model_spec, messages, schema, opts \\ [])

This function is deprecated. Use stream_object/4 with StreamResponse instead.

DEPRECATED: This function will be removed in a future version.

The streaming API has been redesigned to return a composite StreamResponse struct that provides both the stream and metadata. Use stream_object/4 instead:

{:ok, response} = ReqLLM.stream_object(model, messages, schema)
response.stream |> Enum.each(&IO.inspect/1)

For simple object extraction, use:

object = ReqLLM.StreamResponse.object(response)

Legacy Parameters

Same as stream_object/4.

Legacy Examples

ReqLLM.stream_object!("anthropic:claude-3-sonnet", "Generate a character", schema)
|> Enum.each(&IO.inspect/1)

stream_text(model_spec, messages, opts \\ [])

Streams text generation using an AI model with concurrent metadata collection.

Returns a ReqLLM.StreamResponse that provides both real-time token streaming and asynchronous metadata collection (usage, finish_reason). This enables zero-latency content delivery while collecting billing/usage data concurrently.

The streaming implementation uses Finch directly for production-grade performance with HTTP/2 multiplexing and automatic connection pooling.

Parameters

Same as generate_text/3.

Returns

  • {:ok, stream_response} - StreamResponse with stream and metadata task
  • {:error, reason} - Request failed or invalid parameters

Examples

# Real-time streaming
{:ok, response} = ReqLLM.stream_text("anthropic:claude-3-sonnet", "Tell me a story")
response
|> ReqLLM.StreamResponse.tokens()
|> Stream.each(&IO.write/1)
|> Stream.run()

# Concurrent metadata collection
usage = ReqLLM.StreamResponse.usage(response)
#=> %{input_tokens: 15, output_tokens: 42, total_cost: 0.087}

# Simple text collection
text = ReqLLM.StreamResponse.text(response)

# Backward compatibility
{:ok, legacy_response} = ReqLLM.StreamResponse.to_response(response)

StreamResponse Fields

  • stream - Lazy enumerable of StreamChunk structs for real-time consumption
  • metadata_task - Concurrent Task collecting usage and finish_reason
  • cancel - Function to terminate streaming and cleanup resources
  • model - Model specification that generated this response
  • context - Updated conversation context including assistant's response

Performance Notes

The stream is lazy and supports backpressure. Metadata collection happens concurrently and won't block token delivery. Use cancellation for early termination to free resources.

stream_text!(model_spec, messages, opts \\ [])

This function is deprecated. Use stream_text/3 with StreamResponse instead.

DEPRECATED: This function will be removed in a future version.

The streaming API has been redesigned to return a composite StreamResponse struct that provides both the stream and metadata. Use stream_text/3 instead:

{:ok, response} = ReqLLM.stream_text(model, messages)
response.stream |> Enum.each(&IO.write/1)

For simple text extraction, use:

text = ReqLLM.StreamResponse.text(response)

Legacy Behavior

This function currently returns :ok and logs a deprecation warning. It will be formally removed in the next major version.

tool(opts)

@spec tool(keyword()) :: ReqLLM.Tool.t()

Creates a Tool struct for AI model function calling.

Equivalent to Vercel AI SDK's tool() helper, providing type-safe tool definitions with parameter validation. This is a convenience function for creating ReqLLM.Tool structs.

Parameters

  • opts - Tool definition options (keyword list)

Options

  • :name - Tool name (required, must be valid identifier)
  • :description - Tool description for AI model (required)
  • :parameters - Parameter schema as NimbleOptions keyword list (optional)
  • :callback - Callback function or MFA tuple (required)

Examples

# Simple tool with no parameters
tool = ReqLLM.tool(
  name: "get_time",
  description: "Get the current time",
  callback: fn _args -> {:ok, DateTime.utc_now()} end
)

# Tool with parameters
weather_tool = ReqLLM.tool(
  name: "get_weather",
  description: "Get current weather for a location",
  parameters: [
    location: [type: :string, required: true, doc: "City name"],
    units: [type: :string, default: "metric", doc: "Temperature units"]
  ],
  callback: {WeatherAPI, :fetch_weather}
)