Skip to content
Kward Search API index

Class: Kward::TypeSafeClient

Inherits:
Object
  • Object
show all
Defined in:
lib/kward/model/typesafe_client.rb

Overview

HTTP client for TypeSafe's structured System One evaluation endpoint.

Defined Under Namespace

Classes: RequestError

Constant Summary collapse

DEFAULT_ENDPOINT =
"https://api.typesafe.ai/v1/systemone"
DEFAULT_MODEL =
"jev-latest"
MAX_STATE_BYTES =
100_000
MAX_QUESTIONS =
100
HTTP_TIMEOUT_SECONDS =
30

Instance Method Summary collapse

Constructor Details

#initialize(api_key: ENV["TYPESAFE_API_KEY"], endpoint: DEFAULT_ENDPOINT, http: Net::HTTP) ⇒ TypeSafeClient

Returns a new instance of TypeSafeClient.



25
26
27
28
29
# File 'lib/kward/model/typesafe_client.rb', line 25

def initialize(api_key: ENV["TYPESAFE_API_KEY"], endpoint: DEFAULT_ENDPOINT, http: Net::HTTP)
  @api_key = api_key.to_s.strip
  @endpoint = URI(endpoint)
  @http = http
end

Instance Method Details

#available? ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/kward/model/typesafe_client.rb', line 31

def available?
  !@api_key.empty?
end

#evaluate(state:, questions:, model: DEFAULT_MODEL, cancellation: nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/kward/model/typesafe_client.rb', line 35

def evaluate(state:, questions:, model: DEFAULT_MODEL, cancellation: nil)
  raise ArgumentError, "TypeSafe API key is not configured" unless available?

  cancellation&.raise_if_cancelled!
  request = Net::HTTP::Post.new(@endpoint)
  request["Authorization"] = "Bearer #{@api_key}"
  request["Content-Type"] = "application/json"
  request["Accept"] = "application/json"
  Http.apply_user_agent(request)
  request.body = JSON.dump({ state: state, model: model, questions: questions })

  response_body = nil
  @http.start(@endpoint.hostname, @endpoint.port, use_ssl: @endpoint.scheme == "https", read_timeout: HTTP_TIMEOUT_SECONDS) do |http|
    cancellation&.on_cancel { close_http(http) }
    cancellation&.raise_if_cancelled!
    response = http.request(request)
    response_body = response.body.to_s
    unless response.is_a?(Net::HTTPSuccess)
      raise RequestError.new(status: response.code, message: error_message(response.code, response_body))
    end
  end
  cancellation&.raise_if_cancelled!
  JSON.parse(response_body)
rescue JSON::ParserError
  raise RequestError.new(status: 200, message: "TypeSafe returned invalid JSON")
end