class RubyConversations::Client

HTTP client for interacting with the conversations API

def build_client

def build_client
  Faraday.new(url: @url) do |faraday|
    faraday.request :json
    faraday.response :json
    faraday.request :authorization, 'Bearer', -> { current_jwt }
    faraday.adapter Faraday.default_adapter
  end
end

def current_jwt

def current_jwt
  refresh_jwt if token_expired?
  @jwt_token
end

def fetch_all_conversation_templates

Returns:
  • (Array) - Array of template data including messages and prompts
def fetch_all_conversation_templates
  response = client.get('api/ai_conversations')
  handle_response(response)
end

def fetch_conversation_template(template_name)

Returns:
  • (Hash) - The template data including messages and prompts

Parameters:
  • template_name (String) -- The name of the template to fetch
def fetch_conversation_template(template_name)
  response = client.get("api/ai_conversations/#{template_name}")
  handle_response(response)
end

def fetch_prompt(name)

Returns:
  • (Hash) - The prompt attributes

Parameters:
  • name (String) -- The name of the prompt to fetch
def fetch_prompt(name)
  response = client.get("api/prompts/#{name}")
  data = handle_response(response)
  map_prompt_attributes(data)
end

def handle_response(response)

def handle_response(response)
  return response.body if response.success?
  @logger.error("API request failed: #{response.body.inspect}")
  raise RubyConversations::ClientError.new("API request failed: #{response.body}", status_code: response.status)
end

def initialize(url:, jwt_secret:)

Parameters:
  • jwt_secret (String, #call) -- The JWT secret or a callable that returns a JWT token
  • url (String) -- The base URL for the API
def initialize(url:, jwt_secret:)
  @url = url
  @jwt_secret = jwt_secret
  @jwt_token = nil
  @jwt_expiration = nil
  @logger = Logger.new($stdout)
  @client = build_client
end

def map_prompt_attributes(data)

def map_prompt_attributes(data)
  PROMPT_ATTRIBUTES.each_with_object({}) do |attr_name, attrs|
    attrs[attr_name.to_sym] = data[attr_name]
  end
end

def refresh_callable_jwt

def refresh_callable_jwt
  @jwt_token = @jwt_secret.call
  decoded_token = JWT.decode(@jwt_token, nil, false).first
  @jwt_expiration = decoded_token['exp']
end

def refresh_jwt

def refresh_jwt
  if @jwt_secret.respond_to?(:call)
    refresh_callable_jwt
  else
    refresh_static_jwt
  end
end

def refresh_static_jwt

def refresh_static_jwt
  @jwt_expiration = Time.now.to_i + 3600 # 1 hour
  payload = { exp: @jwt_expiration, iat: Time.now.to_i }
  @jwt_token = JWT.encode(payload, @jwt_secret, 'HS256')
end

def store_conversation(conversation)

Raises:
  • (Error) - If the API response is missing a conversation ID

Returns:
  • (Hash) - The API response data

Parameters:
  • conversation (Conversation) -- The conversation to store
def store_conversation(conversation)
  response = client.post('api/ai_conversations', conversation.conversation_attributes_for_storage)
  data = handle_response(response)
  raise RubyConversations::Error, 'API response missing conversation ID' unless data['id'].present?
  conversation.id = data['id']
  data
end

def store_conversation_or_message(conversation, message)

Returns:
  • (Hash) - The API response data

Parameters:
  • message (Message) -- The message to store
  • conversation (Conversation) -- The conversation to store
def store_conversation_or_message(conversation, message)
  if conversation.id.present?
    store_message(conversation, message)
  else
    store_conversation(conversation)
  end
end

def store_message(conversation, message)

Returns:
  • (Hash) - The API response data

Parameters:
  • message (Message) -- The message to store
  • conversation (Conversation) -- The conversation to add the message to
def store_message(conversation, message)
  response = client.post("api/ai_conversations/#{conversation.id}/ai_messages",
                         { ai_message: message.attributes_for_api })
  handle_response(response)
end

def token_expired?

def token_expired?
  [@jwt_token, @jwt_expiration].any?(&:nil?) || Time.now.to_i >= @jwt_expiration
end