Class: OllamaAgent::LLM::AnthropicClient

Inherits:
Object
  • Object
show all
Defined in:
lib/ollama_agent/llm/anthropic_client.rb

Overview

Direct HTTPS client for Anthropic Messages API (no shell-out). Retry backoff uses wall-clock sleep (not for saga logical clocks).

rubocop:disable Metrics/ClassLength – single-file HTTP + SSE client without extra gem deps

Constant Summary collapse

API_URL =
"https://api.anthropic.com/v1/messages"
ANTHROPIC_VERSION =
"2023-06-01"
RETRYABLE_STATUSES =
[429, 502, 503, 504].freeze
DEFAULT_MAX_ATTEMPTS =
3
DEFAULT_BASE_DELAY =
1.0
BACKOFF_FACTOR =
2.0
JITTER_LOW =
0.75
JITTER_HIGH =
1.25

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key:, model: "claude-opus-4-7", timeout_seconds: nil, open_timeout_seconds: nil, request_timeout_seconds: nil, max_attempts: DEFAULT_MAX_ATTEMPTS, sleep: Kernel.method(:sleep), random: Random.new, http_client: Net::HTTP) ⇒ AnthropicClient

rubocop:disable Metrics/ParameterLists – explicit test hooks + timeout knobs

Parameters:

  • open_timeout_seconds (Integer) (defaults to: nil)

    TCP connect timeout

  • request_timeout_seconds (Integer) (defaults to: nil)

    read timeout per request

  • timeout_seconds (Integer, nil) (defaults to: nil)

    when set, used for both open and read (backwards compatible)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ollama_agent/llm/anthropic_client.rb', line 29

def initialize(
  api_key:,
  model: "claude-opus-4-7",
  timeout_seconds: nil,
  open_timeout_seconds: nil,
  request_timeout_seconds: nil,
  max_attempts: DEFAULT_MAX_ATTEMPTS,
  sleep: Kernel.method(:sleep),
  random: Random.new,
  http_client: Net::HTTP
)
  @api_key = api_key
  @model = model
  @open_timeout = Integer(open_timeout_seconds || timeout_seconds || 180)
  @request_timeout = Integer(request_timeout_seconds || timeout_seconds || 180)
  @max_attempts = Integer(max_attempts)
  @sleep = sleep
  @random = random
  @http_client = http_client
end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



23
24
25
# File 'lib/ollama_agent/llm/anthropic_client.rb', line 23

def model
  @model
end

Instance Method Details

#chat(messages:, system: nil, max_tokens: 8192) ⇒ Hash

Returns :content (assistant text), :stop_reason, :usage (symbol keys).

Returns:

  • (Hash)

    :content (assistant text), :stop_reason, :usage (symbol keys)

Raises:



52
53
54
55
56
57
58
# File 'lib/ollama_agent/llm/anthropic_client.rb', line 52

def chat(messages:, system: nil, max_tokens: 8192)
  payload = build_body(messages: messages, system: system, max_tokens: max_tokens, stream: false)
  response = perform_request(payload)
  raise AnthropicAPIError, error_message_for(response) unless response.code == "200"

  parse_success_response(response.body)
end

#stream_chat(messages:, system: nil, max_tokens: 8192, &block) ⇒ Object

Streams message deltas (SSE). Yields hashes { delta:, stop_reason: } (symbols).

Raises:

  • (ArgumentError)


61
62
63
64
65
66
# File 'lib/ollama_agent/llm/anthropic_client.rb', line 61

def stream_chat(messages:, system: nil, max_tokens: 8192, &block)
  raise ArgumentError, "stream_chat requires a block" unless block

  payload = build_body(messages: messages, system: system, max_tokens: max_tokens, stream: true)
  perform_stream_request(payload, &block)
end