# Anthropic Elixir API Wrapper
This unofficial Elixir wrapper provides a convenient way to interact with the [Anthropic API](https://docs.anthropic.com/claude/reference/getting-started-with-the-api), specifically designed to work with the [Claude LLM model](https://docs.anthropic.com/claude/docs/intro-to-claude). It includes modules for handling configuration, preparing requests, sending them to the API, and processing responses.
## Features
- Easy setup and configuration.
- Support for registering and invoking tools.
- Support for sending messages and receiving responses from the Claude LLM model.
- Error handling for both client and server-side issues.
- Customizable request parameters to tweak the behavior of the API.
## To-dos
- Add streaming handling
- Allow for Tool do define different models.
## Installation
The package can be installed by adding `anthropic` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:anthropic, "~> 0.4.0", hex: :anthropic_community}
]
end
```
## Configuration
Add or create a config file to provide the `api_key` as in the example below. Or pass an `:api_key` as option on `Anthropic.new(api_key: "key")`
```elixir
# config/config.exs
import Config
config :anthropic,
api_key: System.get_env("ANTHROPIC_API_KEY")
```
## Usage
### Basic Conversation
```elixir
{:ok, response, request} =
Anthropic.new()
|> Anthropic.add_system_message("You are a helpful assistant")
|> Anthropic.add_user_message("Explain monads in computer science. Be concise.")
|> Anthropic.request_next_message()
```
The `response` will hold a map with the API response.
```elixir
%{
id: "msg_013Zva2CMHLNnXjNJJKqJ2EF",
content: [
%{type: "text", content: "Monads in computer science are a concept borrowed from category theory in mathematics, applied to abstract and manage complexity in functional programming. They provide a framework for chaining operations together step by step, where each step is processed in a context that can handle aspects like computations with side effects (e.g., state changes, I/O operations), errors, or asynchronous operations, without losing the purity of functional programming."}
],
model: "claude-3-opus-20240229",
role: "assistant",
stop_reason: "end_turn",
stop_sequence: null,
type: "message",
usage: %{
"input_tokens" => 10,
"output_tokens" => 25
}
}
```
The conversation can continue:
```elixir
request
|> Anthropic.add_user_message("Hold on right there! ELI5!")
|> Anthropic.request_next_message()
```
### Registering and Invoking Tools
You can register tools that the AI can use to perform specific tasks. Here's an example:
```elixir
defmodule MyApp.WeatherTool do
@behaviour Anthropic.Tool.ToolBehaviour
@impl true
def description do
"""
Tool description to explain AI how and when to use it
"""
end
@impl true
def parameters do
[
{:location, :string, "The city and state of the location you need the weather"}
]
end
@impl true
def invoke(location: location) do
# Implement the tool's functionality here
# ...
# and return a string
end
end
{:ok, response, request} =
Anthropic.new()
|> Anthropic.register_tool(MyApp.WeatherTool)
|> Anthropic.add_user_message("Use the MyApp.WeatherTool to perform a task.")
|> Anthropic.request_next_message()
|> Anthropic.process_invocations()
```