feat: simplify make api call
This commit is contained in:
@@ -78,19 +78,15 @@ class Captain::BaseEditorService
|
||||
"#{endpoint}/v1"
|
||||
end
|
||||
|
||||
def make_api_call(payload)
|
||||
payload = payload.deep_stringify_keys
|
||||
instrumentation_params = build_instrumentation_params(payload)
|
||||
def make_api_call(model:, messages:)
|
||||
instrumentation_params = build_instrumentation_params(model, messages)
|
||||
|
||||
instrument_llm_call(instrumentation_params) do
|
||||
execute_ruby_llm_request(payload)
|
||||
execute_ruby_llm_request(model: model, messages: messages)
|
||||
end
|
||||
end
|
||||
|
||||
def execute_ruby_llm_request(payload)
|
||||
messages = payload['messages']
|
||||
model = payload['model']
|
||||
|
||||
def execute_ruby_llm_request(model:, messages:)
|
||||
Llm::Config.with_api_key(api_key, api_base: api_base) do |context|
|
||||
chat = context.chat(model: model)
|
||||
setup_chat_with_messages(chat, messages)
|
||||
@@ -109,24 +105,24 @@ class Captain::BaseEditorService
|
||||
end
|
||||
|
||||
def apply_system_instructions(chat, messages)
|
||||
system_msg = messages.find { |m| m['role'] == 'system' }
|
||||
chat.with_instructions(system_msg['content']) if system_msg
|
||||
system_msg = messages.find { |m| m[:role] == 'system' }
|
||||
chat.with_instructions(system_msg[:content]) if system_msg
|
||||
end
|
||||
|
||||
def send_conversation_messages(chat, messages)
|
||||
conversation_messages = messages.reject { |m| m['role'] == 'system' }
|
||||
conversation_messages = messages.reject { |m| m[:role] == 'system' }
|
||||
|
||||
return nil if conversation_messages.empty?
|
||||
|
||||
return chat.ask(conversation_messages.first['content']) if conversation_messages.length == 1
|
||||
return chat.ask(conversation_messages.first[:content]) if conversation_messages.length == 1
|
||||
|
||||
add_conversation_history(chat, conversation_messages[0...-1])
|
||||
chat.ask(conversation_messages.last['content'])
|
||||
chat.ask(conversation_messages.last[:content])
|
||||
end
|
||||
|
||||
def add_conversation_history(chat, messages)
|
||||
messages.each do |msg|
|
||||
chat.add_message(role: msg['role'].to_sym, content: msg['content'])
|
||||
chat.add_message(role: msg[:role].to_sym, content: msg[:content])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -142,15 +138,15 @@ class Captain::BaseEditorService
|
||||
}
|
||||
end
|
||||
|
||||
def build_instrumentation_params(parsed_body)
|
||||
def build_instrumentation_params(model, messages)
|
||||
{
|
||||
span_name: "llm.#{event_name}",
|
||||
account_id: account.id,
|
||||
conversation_id: conversation&.display_id,
|
||||
feature_name: event_name,
|
||||
model: parsed_body['model'],
|
||||
messages: parsed_body['messages'],
|
||||
temperature: parsed_body['temperature']
|
||||
model: model,
|
||||
messages: messages,
|
||||
temperature: nil
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -2,10 +2,16 @@ class Captain::LabelSuggestionService < Captain::BaseEditorService
|
||||
CACHEABLE_EVENTS = %w[label_suggestion].freeze
|
||||
|
||||
def label_suggestion_message
|
||||
payload = label_suggestion_body
|
||||
return nil if payload.blank?
|
||||
content = labels_with_messages
|
||||
return nil if content.blank?
|
||||
|
||||
response = make_api_call(payload)
|
||||
response = make_api_call(
|
||||
model: GPT_MODEL, # TODO: Use separate model for label suggestion
|
||||
messages: [
|
||||
{ role: 'system', content: prompt_from_file('label_suggestion') },
|
||||
{ role: 'user', content: content }
|
||||
]
|
||||
)
|
||||
return response if response[:error].present?
|
||||
|
||||
# LLMs are not deterministic - sometimes response includes "Labels:" prefix
|
||||
@@ -15,27 +21,6 @@ class Captain::LabelSuggestionService < Captain::BaseEditorService
|
||||
|
||||
private
|
||||
|
||||
def label_suggestion_body
|
||||
# TODO: Enable based on separate model and settings source
|
||||
# Future: Different model for label suggestion
|
||||
# Future: Settings-based feature gating
|
||||
# For now: Enabled by default when API key available
|
||||
|
||||
content = labels_with_messages
|
||||
return value_from_cache if content.blank?
|
||||
|
||||
{
|
||||
model: GPT_MODEL, # TODO: Use separate model for label suggestion
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt_from_file('label_suggestion')
|
||||
},
|
||||
{ role: 'user', content: content }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def labels_with_messages
|
||||
return nil unless valid_conversation?(conversation)
|
||||
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
class Captain::ReplySuggestionService < Captain::BaseEditorService
|
||||
def reply_suggestion_message
|
||||
make_api_call(reply_suggestion_body)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reply_suggestion_body
|
||||
{
|
||||
make_api_call(
|
||||
model: GPT_MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: prompt_from_file('reply') }
|
||||
].concat(conversation_messages)
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,14 +37,13 @@ class Captain::RewriteService < Captain::BaseEditorService
|
||||
private
|
||||
|
||||
def call_llm_with_prompt(system_content, user_content = event['data']['content'])
|
||||
payload = {
|
||||
make_api_call(
|
||||
model: GPT_MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: system_content },
|
||||
{ role: 'user', content: user_content }
|
||||
]
|
||||
}
|
||||
make_api_call(payload)
|
||||
)
|
||||
end
|
||||
|
||||
def render_liquid_template(template_content, variables = {})
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
class Captain::SummaryService < Captain::BaseEditorService
|
||||
def summarize_message
|
||||
make_api_call(summarize_body)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def summarize_body
|
||||
{
|
||||
make_api_call(
|
||||
model: GPT_MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: prompt_from_file('summary') },
|
||||
{ role: 'user', content: conversation.to_llm_text(include_contact_details: false) }
|
||||
]
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user