Class: Prescient::Provider::Anthropic

Inherits:
Base
  • Object
show all
Includes:
HTTParty
Defined in:
lib/prescient/provider/anthropic.rb

Overview

Since:

  • 1.0.0

Instance Attribute Summary

Attributes inherited from Base

#options

Instance Method Summary collapse

Methods inherited from Base

#apply_format_template, #available?, #build_format_data, #build_prompt, #calculate_field_match_score, #clean_text, #default_context_configs, #default_prompt_templates, #detect_context_type, #extract_configured_fields, #extract_embedding_text, #extract_text_values, #fallback_format_hash, #find_best_field_match, #format_context_item, #format_hash_item, #handle_errors, #match_context_by_fields, #normalize_embedding, #resolve_context_config

Constructor Details

#initialize(**options) ⇒ Anthropic

Returns a new instance of Anthropic.

Since:

  • 1.0.0



10
11
12
13
# File 'lib/prescient/provider/anthropic.rb', line 10

def initialize(**options)
  super
  self.class.default_timeout(@options[:timeout] || 60)
end

Instance Method Details

#generate_embedding(_text, **_options) ⇒ Object

Raises:

Since:

  • 1.0.0



15
16
17
18
19
# File 'lib/prescient/provider/anthropic.rb', line 15

def generate_embedding(_text, **_options)
  # Anthropic doesn't provide embedding API, raise error
  raise Prescient::Error,
        'Anthropic provider does not support embeddings. Use OpenAI or HuggingFace for embeddings.'
end

#generate_response(prompt, context_items = [], **options) ⇒ Object

Since:

  • 1.0.0



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/prescient/provider/anthropic.rb', line 21

def generate_response(prompt, context_items = [], **options)
  handle_errors do
    formatted_prompt = build_prompt(prompt, context_items)

    response = self.class.post('/v1/messages',
                               headers: {
                                 'Content-Type'      => 'application/json',
                                 'x-api-key'         => @options[:api_key],
                                 'anthropic-version' => '2023-06-01',
                               },
                               body:    {
                                 model:       @options[:model],
                                 max_tokens:  options[:max_tokens] || 2000,
                                 temperature: options[:temperature] || 0.7,
                                 messages:    [
                                   {
                                     role:    'user',
                                     content: formatted_prompt,
                                   },
                                 ],
                               }.to_json)

    validate_response!(response, 'text generation')

    content = response.parsed_response.dig('content', 0, 'text')
    raise Prescient::InvalidResponseError, 'No response generated' unless content

    {
      response:        content.strip,
      model:           @options[:model],
      provider:        'anthropic',
      processing_time: nil,
      metadata:        {
        usage: response.parsed_response['usage'],
      },
    }
  end
end

#health_checkObject

Since:

  • 1.0.0



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/prescient/provider/anthropic.rb', line 60

def health_check
  handle_errors do
    # Test with a simple message
    response = self.class.post('/v1/messages',
                               headers: {
                                 'Content-Type'      => 'application/json',
                                 'x-api-key'         => @options[:api_key],
                                 'anthropic-version' => '2023-06-01',
                               },
                               body:    {
                                 model:      @options[:model],
                                 max_tokens: 10,
                                 messages:   [
                                   {
                                     role:    'user',
                                     content: 'Test',
                                   },
                                 ],
                               }.to_json)

    if response.success?
      {
        status:   'healthy',
        provider: 'anthropic',
        model:    @options[:model],
        ready:    true,
      }
    else
      {
        status:   'unhealthy',
        provider: 'anthropic',
        error:    "HTTP #{response.code}",
        message:  response.message,
      }
    end
  end
rescue Prescient::ConnectionError => e
  {
    status:   'unavailable',
    provider: 'anthropic',
    error:    e.class.name,
    message:  e.message,
  }
end

#list_modelsObject

Since:

  • 1.0.0



105
106
107
108
109
110
111
112
# File 'lib/prescient/provider/anthropic.rb', line 105

def list_models
  # Anthropic doesn't provide a models list API
  [
    { name: 'claude-3-haiku-20240307', type: 'text' },
    { name: 'claude-3-sonnet-20240229', type: 'text' },
    { name: 'claude-3-opus-20240229', type: 'text' },
  ]
end

#validate_configuration!Object (protected)

Raises:

Since:

  • 1.0.0



116
117
118
119
120
121
122
123
# File 'lib/prescient/provider/anthropic.rb', line 116

def validate_configuration!
  required_options = [:api_key, :model]
  missing_options = required_options.select { |opt| @options[opt].nil? }

  return unless missing_options.any?

  raise Prescient::Error, "Missing required options: #{missing_options.join(', ')}"
end

#validate_response!(response, operation) ⇒ Object (private)

Since:

  • 1.0.0



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/prescient/provider/anthropic.rb', line 127

def validate_response!(response, operation)
  return if response.success?

  case response.code
  when 400
    raise Prescient::Error, "Bad request for #{operation}: #{response.body}"
  when 401
    raise Prescient::AuthenticationError, "Authentication failed for #{operation}"
  when 403
    raise Prescient::AuthenticationError, "Forbidden access for #{operation}"
  when 429
    raise Prescient::RateLimitError, "Rate limit exceeded for #{operation}"
  when 500..599
    raise Prescient::Error, "Anthropic server error during #{operation}: #{response.body}"
  else
    raise Prescient::Error,
          "Anthropic request failed for #{operation}: HTTP #{response.code} - #{response.message}"
  end
end