Claudio.Messages (Claudio v0.5.0)

View Source

Client for the Anthropic Messages API.

This module provides functions for creating messages, counting tokens, and working with streaming responses. It supports both a structured Request/Response API and a legacy map-based API for backward compatibility.

The new API provides type-safe request building and structured response handling:

alias Claudio.Messages.{Request, Response}

# Build a request
request = Request.new("claude-3-5-sonnet-20241022")
|> Request.add_message(:user, "Hello!")
|> Request.set_max_tokens(1024)
|> Request.set_temperature(0.7)

# Create message
{:ok, response} = Claudio.Messages.create(client, request)

# Extract text
text = Response.get_text(response)

Features

  • Streaming: Real-time response streaming with SSE parsing
  • Tool calling: Function calling with structured schemas
  • Prompt caching: Cache large contexts to reduce costs
  • Vision: Send images for analysis
  • Token counting: Estimate costs before making requests
  • Type safety: Structured Request/Response types

Streaming

For streaming responses, enable streaming and consume events:

request = Request.new("claude-3-5-sonnet-20241022")
|> Request.add_message(:user, "Tell me a story")
|> Request.set_max_tokens(1024)
|> Request.enable_streaming()

{:ok, stream_response} = Claudio.Messages.create(client, request)

# Parse and accumulate text
text = stream_response.body
|> Claudio.Messages.Stream.parse_events()
|> Claudio.Messages.Stream.accumulate_text()

IO.puts(text)

Tool Calling

Define and use tools for function calling:

alias Claudio.Tools

tool = Tools.define_tool("get_weather", "Get weather", %{
  type: "object",
  properties: %{location: %{type: "string"}},
  required: ["location"]
})

request = Request.new("claude-3-5-sonnet-20241022")
|> Request.add_message(:user, "What's the weather?")
|> Request.add_tool(tool)
|> Request.set_max_tokens(1024)

{:ok, response} = Claudio.Messages.create(client, request)

# Check for tool uses
if Tools.has_tool_uses?(response) do
  tool_uses = Tools.extract_tool_uses(response)
  # Execute tools and continue conversation...
end

Prompt Caching

Cache large contexts to reduce costs (up to 90% savings):

request = Request.new("claude-3-5-sonnet-20241022")
|> Request.set_system_with_cache("Large context here...", ttl: "5m")
|> Request.add_message(:user, "Question about context")
|> Request.set_max_tokens(1024)

{:ok, response} = Claudio.Messages.create(client, request)

# Check cache metrics
IO.inspect(response.usage.cache_read_input_tokens)

Legacy API (Backward Compatible)

The original API using raw maps is still supported:

{:ok, response} = Claudio.Messages.create_message(client, %{
  "model" => "claude-3-5-sonnet-20241022",
  "max_tokens" => 1024,
  "messages" => [%{"role" => "user", "content" => "Hello"}]
})

Error Handling

All functions return {:ok, result} or {:error, reason} tuples:

case Claudio.Messages.create(client, request) do
  {:ok, response} ->
    IO.puts("Success!")

  {:error, %Claudio.APIError{} = error} ->
    IO.puts("API Error: #{error.message}")

  {:error, reason} ->
    IO.puts("Error: #{inspect(reason)}")
end

Summary

Functions

Counts tokens for a message request.

Creates a message using the new structured API.

Creates a message (legacy API, backward compatible).

Functions

count_tokens(client, request)

@spec count_tokens(Req.Request.t(), map() | Claudio.Messages.Request.t()) ::
  {:ok, map()} | {:error, Claudio.APIError.t() | term()}

Counts tokens for a message request.

Example

{:ok, count} = Claudio.Messages.count_tokens(client, %{
  "model" => "claude-3-5-sonnet-20241022",
  "messages" => [%{"role" => "user", "content" => "Hello"}]
})

IO.puts("Input tokens: #{count.input_tokens}")

create(client, request)

Creates a message using the new structured API.

Accepts either a Request struct or a raw map (for backward compatibility). Returns either a Response struct or raw stream data for streaming requests.

Examples

# Using Request builder
request = Request.new("claude-3-5-sonnet-20241022")
|> Request.add_message(:user, "Hello!")
|> Request.set_max_tokens(1024)

{:ok, response} = Claudio.Messages.create(client, request)

# Using raw map (backward compatible)
{:ok, response} = Claudio.Messages.create(client, %{
  "model" => "claude-3-5-sonnet-20241022",
  "max_tokens" => 1024,
  "messages" => [%{"role" => "user", "content" => "Hello"}]
})

create_message(client, payload)

@spec create_message(Req.Request.t(), map()) ::
  {:ok, map() | Req.Response.t()} | {:error, term()}

Creates a message (legacy API, backward compatible).

This function maintains backward compatibility with the original implementation. For new code, consider using create/2 instead.