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
-
(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)
-
(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)
-
(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:)
-
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)
-
(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)
-
(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)
-
(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