feat: Add support for Langfuse LLM Tracing via OTEL (#12905)
This PR adds LLM instrumentation on langfuse for ai-editor feature ## Type of change New feature (non-breaking change which adds functionality) Needs langfuse account and env vars to be set ## How Has This Been Tested? I configured personal langfuse credentials and instrumented the app, traces can be seen in langfuse. each conversation is one session. <img width="1683" height="714" alt="image" src="https://github.com/user-attachments/assets/3fcba1c9-63cf-44b9-a355-fd6608691559" /> <img width="1446" height="172" alt="image" src="https://github.com/user-attachments/assets/dfa6e98f-4741-4e04-9a9e-078d1f01e97b" /> ## Checklist: - [x ] My code follows the style guidelines of this project - [ x] I have performed a self-review of my code - [ x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: aakashb95 <aakash@chatwoot.com> Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
class Integrations::OpenaiBaseService
|
||||
include Integrations::LlmInstrumentation
|
||||
|
||||
# gpt-4o-mini supports 128,000 tokens
|
||||
# 1 token is approx 4 characters
|
||||
# sticking with 120000 to be safe
|
||||
@@ -87,21 +89,57 @@ class Integrations::OpenaiBaseService
|
||||
end
|
||||
|
||||
def make_api_call(body)
|
||||
headers = {
|
||||
parsed_body = JSON.parse(body)
|
||||
instrumentation_params = build_instrumentation_params(parsed_body)
|
||||
|
||||
instrument_llm_call(instrumentation_params) do
|
||||
execute_api_request(body, parsed_body['messages'])
|
||||
end
|
||||
end
|
||||
|
||||
def build_instrumentation_params(parsed_body)
|
||||
{
|
||||
span_name: "llm.#{event_name}",
|
||||
account_id: hook.account_id,
|
||||
conversation_id: conversation&.display_id,
|
||||
feature_name: event_name,
|
||||
model: parsed_body['model'],
|
||||
messages: parsed_body['messages'],
|
||||
temperature: parsed_body['temperature']
|
||||
}
|
||||
end
|
||||
|
||||
def execute_api_request(body, messages)
|
||||
Rails.logger.info("OpenAI API request: #{body}")
|
||||
response = HTTParty.post(api_url, headers: api_headers, body: body)
|
||||
Rails.logger.info("OpenAI API response: #{response.body}")
|
||||
|
||||
parse_api_response(response, messages)
|
||||
end
|
||||
|
||||
def api_headers
|
||||
{
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => "Bearer #{hook.settings['api_key']}"
|
||||
}
|
||||
end
|
||||
|
||||
Rails.logger.info("OpenAI API request: #{body}")
|
||||
response = HTTParty.post(api_url, headers: headers, body: body)
|
||||
Rails.logger.info("OpenAI API response: #{response.body}")
|
||||
def parse_api_response(response, messages)
|
||||
return build_error_response(response, messages) unless response.success?
|
||||
|
||||
return { error: response.parsed_response, error_code: response.code } unless response.success?
|
||||
parsed_response = JSON.parse(response.body)
|
||||
build_success_response(parsed_response, messages)
|
||||
end
|
||||
|
||||
choices = JSON.parse(response.body)['choices']
|
||||
def build_error_response(response, messages)
|
||||
{ error: response.parsed_response, error_code: response.code, request_messages: messages }
|
||||
end
|
||||
|
||||
return { message: choices.first['message']['content'] } if choices.present?
|
||||
def build_success_response(parsed_response, messages)
|
||||
choices = parsed_response['choices']
|
||||
usage = parsed_response['usage']
|
||||
message_content = choices.present? ? choices.first['message']['content'] : nil
|
||||
|
||||
{ message: nil }
|
||||
{ message: message_content, usage: usage, request_messages: messages }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user