anthropic

package module
v2.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2024 License: Apache-2.0 Imports: 9 Imported by: 4

README

go-anthropic

Go Reference Go Report Card codecov Sanity check

Anthropic Claude API wrapper for Go (Unofficial). Support:

  • Completions
  • Streaming Completions
  • Messages
  • Streaming Messages
  • Vision
  • Tool use

Installation

go get github.com/liushuangls/go-anthropic/v2

Currently, go-anthropic requires Go version 1.21 or greater.

Usage

Messages example usage:
package main

import (
	"errors"
	"fmt"

	"github.com/liushuangls/go-anthropic/v2"
)

func main() {
	client := anthropic.NewClient("your anthropic apikey")
	resp, err := client.CreateMessages(context.Background(), anthropic.MessagesRequest{
		Model: anthropic.ModelClaudeInstant1Dot2,
		Messages: []anthropic.Message{
			anthropic.NewUserTextMessage("What is your name?"),
		},
		MaxTokens: 1000,
	})
	if err != nil {
		var e *anthropic.APIError
		if errors.As(err, &e) {
			fmt.Printf("Messages error, type: %s, message: %s", e.Type, e.Message)
		} else {
			fmt.Printf("Messages error: %v\n", err)
        }
		return
	}
	fmt.Println(resp.Content[0].Text)
}
Messages stream example usage:
package main

import (
	"errors"
	"fmt"

	"github.com/liushuangls/go-anthropic/v2"
)

func main() {
	client := anthropic.NewClient("your anthropic apikey")
	resp, err := client.CreateMessagesStream(context.Background(),  anthropic.MessagesStreamRequest{
		MessagesRequest: anthropic.MessagesRequest{
			Model: anthropic.ModelClaudeInstant1Dot2,
			Messages: []anthropic.Message{
				anthropic.NewUserTextMessage("What is your name?"),
			},
			MaxTokens:   1000,
		},
		OnContentBlockDelta: func(data anthropic.MessagesEventContentBlockDeltaData) {
			fmt.Printf("Stream Content: %s\n", data.Delta.Text)
		},
	})
	if err != nil {
		var e *anthropic.APIError
		if errors.As(err, &e) {
			fmt.Printf("Messages stream error, type: %s, message: %s", e.Type, e.Message)
		} else {
			fmt.Printf("Messages stream error: %v\n", err)
        }
		return
	}
	fmt.Println(resp.Content[0].Text)
}
Other examples:
Messages Vision example
package main

import (
	"errors"
	"fmt"

	"github.com/liushuangls/go-anthropic/v2"
)

func main() {
	client := anthropic.NewClient("your anthropic apikey")

	imagePath := "xxx"
	imageMediaType := "image/jpeg"
	imageFile, err := os.Open(imagePath)
	if err != nil {
		panic(err)
	}
	imageData, err := io.ReadAll(imageFile)
	if err != nil {
		panic(err)
	}

	resp, err := client.CreateMessages(context.Background(), anthropic.MessagesRequest{
		Model: anthropic.ModelClaude3Opus20240229,
		Messages: []anthropic.Message{
			{
				Role: anthropic.RoleUser,
				Content: []anthropic.MessageContent{
					anthropic.NewImageMessageContent(anthropic.MessageContentImageSource{
						Type:      "base64",
						MediaType: imageMediaType,
						Data:      imageData,
					}),
					anthropic.NewTextMessageContent("Describe this image."),
				},
			},
		},
		MaxTokens: 1000,
	})
	if err != nil {
		var e *anthropic.APIError
		if errors.As(err, &e) {
			fmt.Printf("Messages error, type: %s, message: %s", e.Type, e.Message)
		} else {
			fmt.Printf("Messages error: %v\n", err)
        }
		return
	}
	fmt.Println(resp.Content[0].Text)
}
Messages Tool use example
package main

import (
	"context"
	"fmt"

	"github.com/liushuangls/go-anthropic/v2"
	"github.com/liushuangls/go-anthropic/v2/jsonschema"
)

func main() {
	client := anthropic.NewClient(
		"your anthropic apikey",
	)

	request := anthropic.MessagesRequest{
		Model: anthropic.ModelClaude3Haiku20240307,
		Messages: []anthropic.Message{
			anthropic.NewUserTextMessage("What is the weather like in San Francisco?"),
		},
		MaxTokens: 1000,
		Tools: []anthropic.ToolDefinition{
			{
				Name:        "get_weather",
				Description: "Get the current weather in a given location",
				InputSchema: jsonschema.Definition{
					Type: jsonschema.Object,
					Properties: map[string]jsonschema.Definition{
						"location": {
							Type:        jsonschema.String,
							Description: "The city and state, e.g. San Francisco, CA",
						},
						"unit": {
							Type:        jsonschema.String,
							Enum:        []string{"celsius", "fahrenheit"},
							Description: "The unit of temperature, either 'celsius' or 'fahrenheit'",
						},
					},
					Required: []string{"location"},
				},
			},
		},
	}

	resp, err := client.CreateMessages(context.Background(), request)
	if err != nil {
		panic(err)
	}

	request.Messages = append(request.Messages, anthropic.Message{
		Role:    anthropic.RoleAssistant,
		Content: resp.Content,
	})

	var toolUse *anthropic.MessageContentToolUse

	for _, c := range resp.Content {
		if c.Type == anthropic.MessagesContentTypeToolUse {
			toolUse = c.MessageContentToolUse
		}
	}

	if toolUse == nil {
		panic("tool use not found")
	}

	request.Messages = append(request.Messages, anthropic.NewToolResultsMessage(toolUse.ID, "65 degrees", false))

	resp, err = client.CreateMessages(context.Background(), request)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Response: %+v\n", resp)
}

Acknowledgments

The following project had particular influence on go-anthropic is design.

Documentation

Index

Constants

View Source
const (
	ModelClaudeInstant1Dot2    = "claude-instant-1.2"
	ModelClaude2Dot0           = "claude-2.0"
	ModelClaude2Dot1           = "claude-2.1"
	ModelClaude3Opus20240229   = "claude-3-opus-20240229"
	ModelClaude3Sonnet20240229 = "claude-3-sonnet-20240229"
	ModelClaude3Haiku20240307  = "claude-3-haiku-20240307"
)
View Source
const (
	RoleUser      = "user"
	RoleAssistant = "assistant"
)
View Source
const (
	BetaTools20240404 = "tools-2024-04-04"
	BetaTools20240516 = "tools-2024-05-16"
)
View Source
const (
	APIVersion20230601 = "2023-06-01"
)

Variables

View Source
var (
	ErrSteamingNotSupportTools = errors.New("streaming is not yet supported tools")
)
View Source
var (
	ErrTooManyEmptyStreamMessages = errors.New("stream has sent too many empty messages")
)

Functions

This section is empty.

Types

type APIError

type APIError struct {
	Type    ErrType `json:"type"`
	Message string  `json:"message"`
}

APIError provides error information returned by the Anthropic API.

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) IsApiErr

func (e *APIError) IsApiErr() bool

func (*APIError) IsAuthenticationErr

func (e *APIError) IsAuthenticationErr() bool

func (*APIError) IsInvalidRequestErr

func (e *APIError) IsInvalidRequestErr() bool

func (*APIError) IsNotFoundErr

func (e *APIError) IsNotFoundErr() bool

func (*APIError) IsOverloadedErr

func (e *APIError) IsOverloadedErr() bool

func (*APIError) IsPermissionErr

func (e *APIError) IsPermissionErr() bool

func (*APIError) IsRateLimitErr

func (e *APIError) IsRateLimitErr() bool

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(apikey string, opts ...ClientOption) *Client

NewClient create new Anthropic API client

func (*Client) CreateComplete

func (c *Client) CreateComplete(ctx context.Context, request CompleteRequest) (response CompleteResponse, err error)

func (*Client) CreateCompleteStream

func (c *Client) CreateCompleteStream(ctx context.Context, request CompleteStreamRequest) (response CompleteResponse, err error)

func (*Client) CreateMessages

func (c *Client) CreateMessages(ctx context.Context, request MessagesRequest) (response MessagesResponse, err error)

func (*Client) CreateMessagesStream

func (c *Client) CreateMessagesStream(ctx context.Context, request MessagesStreamRequest) (response MessagesResponse, err error)

type ClientConfig

type ClientConfig struct {
	BaseURL     string
	APIVersion  string
	BetaVersion string
	HTTPClient  *http.Client

	EmptyMessagesLimit uint
	// contains filtered or unexported fields
}

ClientConfig is a configuration of a client.

type ClientOption

type ClientOption func(c *ClientConfig)

func WithAPIVersion

func WithAPIVersion(apiVersion string) ClientOption

func WithBaseURL

func WithBaseURL(baseUrl string) ClientOption

func WithBetaVersion

func WithBetaVersion(betaVersion string) ClientOption

func WithEmptyMessagesLimit

func WithEmptyMessagesLimit(limit uint) ClientOption

func WithHTTPClient

func WithHTTPClient(cli *http.Client) ClientOption

type CompleteEvent

type CompleteEvent string
const (
	CompleteEventError      CompleteEvent = "error"
	CompleteEventCompletion CompleteEvent = "completion"
	CompleteEventPing       CompleteEvent = "ping"
)

type CompleteRequest

type CompleteRequest struct {
	Model             string `json:"model"`
	Prompt            string `json:"prompt"`
	MaxTokensToSample int    `json:"max_tokens_to_sample"`

	StopSequences []string       `json:"stop_sequences,omitempty"`
	Temperature   *float32       `json:"temperature,omitempty"`
	TopP          *float32       `json:"top_p,omitempty"`
	TopK          *int           `json:"top_k,omitempty"`
	MetaData      map[string]any `json:"meta_data,omitempty"`
	Stream        bool           `json:"stream,omitempty"`
}

func (*CompleteRequest) SetTemperature

func (c *CompleteRequest) SetTemperature(t float32)

func (*CompleteRequest) SetTopK

func (c *CompleteRequest) SetTopK(k int)

func (*CompleteRequest) SetTopP

func (c *CompleteRequest) SetTopP(p float32)

type CompleteResponse

type CompleteResponse struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Completion string `json:"completion"`
	// possible values are: stop_sequence、max_tokens、null
	StopReason string `json:"stop_reason"`
	Model      string `json:"model"`
	// contains filtered or unexported fields
}

func (*CompleteResponse) Header added in v2.1.0

func (h *CompleteResponse) Header() http.Header

func (*CompleteResponse) SetHeader added in v2.1.0

func (h *CompleteResponse) SetHeader(header http.Header)

type CompleteStreamPingData

type CompleteStreamPingData struct {
	Type string `json:"type"`
}

type CompleteStreamRequest

type CompleteStreamRequest struct {
	CompleteRequest

	OnCompletion func(CompleteResponse)       `json:"-"`
	OnPing       func(CompleteStreamPingData) `json:"-"`
	OnError      func(ErrorResponse)          `json:"-"`
}

type ErrType

type ErrType string
const (
	// ErrTypeInvalidRequest There was an issue with the format or content of your request.
	ErrTypeInvalidRequest ErrType = "invalid_request_error"
	// ErrTypeAuthentication There's an issue with your API key.
	ErrTypeAuthentication ErrType = "authentication_error"
	// ErrTypePermission Your API key does not have permission to use the specified resource.
	ErrTypePermission ErrType = "permission_error"
	// ErrTypeNotFound The requested resource was not found.
	ErrTypeNotFound ErrType = "not_found_error"
	// ErrTypeRateLimit Your account has hit a rate limit.
	ErrTypeRateLimit ErrType = "rate_limit_error"
	// ErrTypeApi An unexpected error has occurred internal to Anthropic's systems.
	ErrTypeApi ErrType = "api_error"
	// ErrTypeOverloaded Anthropic's API is temporarily overloaded.
	ErrTypeOverloaded ErrType = "overloaded_error"
)

type ErrorResponse

type ErrorResponse struct {
	Type  string    `json:"type"`
	Error *APIError `json:"error,omitempty"`
}

type Message

type Message struct {
	Role    string           `json:"role"`
	Content []MessageContent `json:"content"`
}

func NewAssistantTextMessage

func NewAssistantTextMessage(text string) Message

func NewToolResultsMessage

func NewToolResultsMessage(toolUseID, content string, isError bool) Message

func NewUserTextMessage

func NewUserTextMessage(text string) Message

func (Message) GetFirstContent

func (m Message) GetFirstContent() MessageContent

type MessageContent

type MessageContent struct {
	Type MessagesContentType `json:"type"`

	Text *string `json:"text,omitempty"`

	Source *MessageContentImageSource `json:"source,omitempty"`

	*MessageContentToolResult

	*MessageContentToolUse

	PartialJson *string `json:"partial_json,omitempty"`
}

func NewImageMessageContent

func NewImageMessageContent(source MessageContentImageSource) MessageContent

func NewTextMessageContent

func NewTextMessageContent(text string) MessageContent

func NewToolResultMessageContent

func NewToolResultMessageContent(toolUseID, content string, isError bool) MessageContent

func NewToolUseMessageContent

func NewToolUseMessageContent(toolUseID, name string, input json.RawMessage) MessageContent

func (*MessageContent) ConcatText

func (m *MessageContent) ConcatText(s string)

func (*MessageContent) GetText

func (m *MessageContent) GetText() string

func (*MessageContent) MergeContentDelta added in v2.2.0

func (m *MessageContent) MergeContentDelta(mc MessageContent)

type MessageContentImageSource

type MessageContentImageSource struct {
	Type      string `json:"type"`
	MediaType string `json:"media_type"`
	Data      any    `json:"data"`
}

type MessageContentToolResult

type MessageContentToolResult struct {
	ToolUseID *string          `json:"tool_use_id,omitempty"`
	Content   []MessageContent `json:"content,omitempty"`
	IsError   *bool            `json:"is_error,omitempty"`
}

func NewMessageContentToolResult

func NewMessageContentToolResult(toolUseID, content string, isError bool) *MessageContentToolResult

type MessageContentToolUse

type MessageContentToolUse struct {
	ID    string          `json:"id,omitempty"`
	Name  string          `json:"name,omitempty"`
	Input json.RawMessage `json:"input,omitempty"`
}

func (*MessageContentToolUse) UnmarshalInput added in v2.2.0

func (c *MessageContentToolUse) UnmarshalInput(v any) error

type MessagesContentType

type MessagesContentType string
const (
	MessagesContentTypeText           MessagesContentType = "text"
	MessagesContentTypeTextDelta      MessagesContentType = "text_delta"
	MessagesContentTypeImage          MessagesContentType = "image"
	MessagesContentTypeToolResult     MessagesContentType = "tool_result"
	MessagesContentTypeToolUse        MessagesContentType = "tool_use"
	MessagesContentTypeInputJsonDelta MessagesContentType = "input_json_delta"
)

type MessagesEvent

type MessagesEvent string

MessagesEvent docs: https://docs.anthropic.com/claude/reference/messages-streaming

const (
	MessagesEventError             MessagesEvent = "error"
	MessagesEventMessageStart      MessagesEvent = "message_start"
	MessagesEventContentBlockStart MessagesEvent = "content_block_start"
	MessagesEventPing              MessagesEvent = "ping"
	MessagesEventContentBlockDelta MessagesEvent = "content_block_delta"
	MessagesEventContentBlockStop  MessagesEvent = "content_block_stop"
	MessagesEventMessageDelta      MessagesEvent = "message_delta"
	MessagesEventMessageStop       MessagesEvent = "message_stop"
)

type MessagesEventContentBlockDeltaData

type MessagesEventContentBlockDeltaData struct {
	Type  string         `json:"type"`
	Index int            `json:"index"`
	Delta MessageContent `json:"delta"`
}

type MessagesEventContentBlockStartData

type MessagesEventContentBlockStartData struct {
	Type         MessagesEvent  `json:"type"`
	Index        int            `json:"index"`
	ContentBlock MessageContent `json:"content_block"`
}

type MessagesEventContentBlockStopData

type MessagesEventContentBlockStopData struct {
	Type  string `json:"type"`
	Index int    `json:"index"`
}

type MessagesEventMessageDeltaData

type MessagesEventMessageDeltaData struct {
	Type  string           `json:"type"`
	Delta MessagesResponse `json:"delta"`
	Usage MessagesUsage    `json:"usage"`
}

type MessagesEventMessageStartData

type MessagesEventMessageStartData struct {
	Type    MessagesEvent    `json:"type"`
	Message MessagesResponse `json:"message"`
}

type MessagesEventMessageStopData

type MessagesEventMessageStopData struct {
	Type string `json:"type"`
}

type MessagesEventPingData

type MessagesEventPingData struct {
	Type string `json:"type"`
}

type MessagesRequest

type MessagesRequest struct {
	Model     string    `json:"model"`
	Messages  []Message `json:"messages"`
	MaxTokens int       `json:"max_tokens"`

	System        string           `json:"system,omitempty"`
	Metadata      map[string]any   `json:"metadata,omitempty"`
	StopSequences []string         `json:"stop_sequences,omitempty"`
	Stream        bool             `json:"stream,omitempty"`
	Temperature   *float32         `json:"temperature,omitempty"`
	TopP          *float32         `json:"top_p,omitempty"`
	TopK          *int             `json:"top_k,omitempty"`
	Tools         []ToolDefinition `json:"tools,omitempty"`
	ToolChoice    *ToolChoice      `json:"tool_choice,omitempty"`
}

func (*MessagesRequest) SetTemperature

func (m *MessagesRequest) SetTemperature(t float32)

func (*MessagesRequest) SetTopK

func (m *MessagesRequest) SetTopK(k int)

func (*MessagesRequest) SetTopP

func (m *MessagesRequest) SetTopP(p float32)

type MessagesResponse

type MessagesResponse struct {
	ID           string               `json:"id"`
	Type         MessagesResponseType `json:"type"`
	Role         string               `json:"role"`
	Content      []MessageContent     `json:"content"`
	Model        string               `json:"model"`
	StopReason   MessagesStopReason   `json:"stop_reason"`
	StopSequence string               `json:"stop_sequence"`
	Usage        MessagesUsage        `json:"usage"`
	// contains filtered or unexported fields
}

func (MessagesResponse) GetFirstContentText

func (m MessagesResponse) GetFirstContentText() string

GetFirstContentText get Content[0].Text avoid panic

func (*MessagesResponse) Header added in v2.1.0

func (h *MessagesResponse) Header() http.Header

func (*MessagesResponse) SetHeader added in v2.1.0

func (h *MessagesResponse) SetHeader(header http.Header)

type MessagesResponseType

type MessagesResponseType string
const (
	MessagesResponseTypeMessage MessagesResponseType = "message"
	MessagesResponseTypeError   MessagesResponseType = "error"
)

type MessagesStopReason

type MessagesStopReason string
const (
	MessagesStopReasonEndTurn      MessagesStopReason = "end_turn"
	MessagesStopReasonMaxTokens    MessagesStopReason = "max_tokens"
	MessagesStopReasonStopSequence MessagesStopReason = "stop_sequence"
	MessagesStopReasonToolUse      MessagesStopReason = "tool_use"
)

type MessagesStreamRequest

type MessagesStreamRequest struct {
	MessagesRequest

	OnError             func(ErrorResponse)                                     `json:"-"`
	OnPing              func(MessagesEventPingData)                             `json:"-"`
	OnMessageStart      func(MessagesEventMessageStartData)                     `json:"-"`
	OnContentBlockStart func(MessagesEventContentBlockStartData)                `json:"-"`
	OnContentBlockDelta func(MessagesEventContentBlockDeltaData)                `json:"-"`
	OnContentBlockStop  func(MessagesEventContentBlockStopData, MessageContent) `json:"-"`
	OnMessageDelta      func(MessagesEventMessageDeltaData)                     `json:"-"`
	OnMessageStop       func(MessagesEventMessageStopData)                      `json:"-"`
}

type MessagesUsage

type MessagesUsage struct {
	InputTokens  int `json:"input_tokens"`
	OutputTokens int `json:"output_tokens"`
}

type RequestError

type RequestError struct {
	StatusCode int
	Err        error
}

RequestError provides information about generic request errors.

func (*RequestError) Error

func (e *RequestError) Error() string

type Response added in v2.1.0

type Response interface {
	SetHeader(http.Header)
}

type ToolChoice added in v2.2.0

type ToolChoice struct {
	// oneof: auto(default) any tool
	Type string `json:"type"`
	Name string `json:"name,omitempty"`
}

type ToolDefinition

type ToolDefinition struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	// InputSchema is an object describing the tool.
	// You can pass json.RawMessage to describe the schema,
	// or you can pass in a struct which serializes to the proper JSON schema.
	// The jsonschema package is provided for convenience, but you should
	// consider another specialized library if you require more complex schemas.
	InputSchema any `json:"input_schema"`
}

Directories

Path Synopsis
internal
Package jsonschema provides very simple functionality for representing a JSON schema as a (nested) struct.
Package jsonschema provides very simple functionality for representing a JSON schema as a (nested) struct.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL