Class: LittleGhost::Providers::Anthropic

Inherits:
Base
  • Object
show all
Defined in:
lib/little_ghost/providers/anthropic.rb,
lib/little_ghost/providers/anthropic/catalog_source.rb

Overview

Connects a Model to Anthropic's Messages API.

Requests send messages, Tool definitions, attachments, and model settings to the configured Anthropic endpoint. The adapter reads its credential from trusted configuration, honors cancellation and deadlines, and emits LittleGhost StreamEvents. HTTP and response-shape failures become ProviderError subclasses. It uses the built-in HTTP client and does not require Anthropic's SDK.

Defined Under Namespace

Classes: CatalogSource, Normalizer

Constant Summary collapse

DEFAULT_BASE_URL =

:nodoc:

"https://api.anthropic.com/v1/"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#embed, #prepare_request

Constructor Details

#initialize(api_key:, model:, base_url: DEFAULT_BASE_URL, api_version: "2023-06-01", open_timeout: 10, read_timeout: 120, max_response_bytes: Support::HTTPClient::DEFAULT_MAX_RESPONSE_BYTES, transport: nil) ⇒ Anthropic

Creates an Anthropic Messages client for model.

Raises:



29
30
31
32
33
34
35
36
37
38
# File 'lib/little_ghost/providers/anthropic.rb', line 29

def initialize(api_key:, model:, base_url: DEFAULT_BASE_URL, api_version: "2023-06-01",
  open_timeout: 10, read_timeout: 120, max_response_bytes: Support::HTTPClient::DEFAULT_MAX_RESPONSE_BYTES,
  transport: nil, **)
  raise CredentialError, "Anthropic api_key is required" if api_key.to_s.empty?

  @api_key = api_key
  @api_version = api_version
  @model = model
  @transport = transport || Support::HTTPClient.new(base_url:, open_timeout:, read_timeout:, max_response_bytes:)
end

Instance Attribute Details

#modelObject (readonly)

Provider-owned model identifier.



26
27
28
# File 'lib/little_ghost/providers/anthropic.rb', line 26

def model
  @model
end

Class Method Details

.request_optionsObject

Request policy supported by the Anthropic HTTP client.



21
# File 'lib/little_ghost/providers/anthropic.rb', line 21

def self.request_options = %i[max_response_bytes open_timeout read_timeout].freeze

Instance Method Details

#capabilities(metadata: {}) ⇒ Object

Reports tool and structured-output support from model metadata.



67
68
69
70
71
72
73
74
75
# File 'lib/little_ghost/providers/anthropic.rb', line 67

def capabilities(metadata: {})
  parameters = [:supported_parameters]
  ModelCapabilities.new(
    native_structured_output: parameters&.include?("structured_outputs"),
    tools: true,
    tool_choice: true,
    supported_parameters: parameters
  )
end

#stream(request) ⇒ Object

Streams normalized events for request.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/little_ghost/providers/anthropic.rb', line 41

def stream(request)
  return enum_for(__method__, request) unless block_given?

  parser = Support::SSEParser.new
  normalizer = Normalizer.new(model:)
  @transport.stream(
    path: "messages",
    headers: {
      "x-api-key" => @api_key,
      "anthropic-version" => @api_version,
      "content-type" => "application/json",
      "accept" => "text/event-stream"
    },
    body: JSON.generate(request_body(request)),
    cancellation_token: request.cancellation_token,
    deadline: request.deadline
  ) do |chunk|
    parser.<<(chunk).each { |data| normalizer.consume(JSON.parse(data)).each { |event| yield event } }
  end
  parser.finish.each { |data| normalizer.consume(JSON.parse(data)).each { |event| yield event } }
  normalizer.finish.each { |event| yield event }
rescue JSON::ParserError => error
  raise ProtocolError, "Anthropic returned invalid JSON: #{error.message}"
end