fix(captain): compact v1 classifier context

This commit is contained in:
aakashb95
2026-05-01 02:17:57 +05:30
parent 2401a1bc7b
commit 81edeca899
2 changed files with 26 additions and 18 deletions
@@ -42,8 +42,7 @@ class Captain::Llm::AssistantActionClassifierService < Llm::BaseAiService
{
'account_custom_instructions' => account_custom_instructions,
'conversation_context' => context_messages(normalized_messages),
'current_user_message' => current_user_message(normalized_messages),
'conversation_context' => format_conversation_context(normalized_messages),
'assistant_response_to_classify' => assistant_response.to_s
}
end
@@ -55,13 +54,9 @@ class Captain::Llm::AssistantActionClassifierService < Llm::BaseAiService
</account_custom_instructions>
<conversation_context>
#{payload['conversation_context'].to_json}
#{payload['conversation_context']}
</conversation_context>
<current_user_message>
#{payload['current_user_message']}
</current_user_message>
<assistant_response_to_classify>
#{payload['assistant_response_to_classify']}
</assistant_response_to_classify>
@@ -90,14 +85,24 @@ class Captain::Llm::AssistantActionClassifierService < Llm::BaseAiService
(part[:type] || part['type']).to_s == 'text'
end
def current_user_message(messages)
messages.reverse.find { |message| message[:role] == 'user' }&.dig(:content).to_s
def format_conversation_context(messages)
context_messages(messages).filter_map do |message|
content = message[:content].to_s.strip
next if content.blank?
"#{role_label(message[:role])}: #{content}"
end.join("\n")
end
def context_messages(messages)
current_user_index = messages.rindex { |message| message[:role] == 'user' }
prior_messages = current_user_index ? messages[0...current_user_index] : messages
prior_messages.last(MAX_CONTEXT_MESSAGES)
messages.last(MAX_CONTEXT_MESSAGES)
end
def role_label(role)
return 'User' if role == 'user'
return 'Assistant' if role == 'assistant'
role.to_s.titleize
end
def account_custom_instructions
@@ -44,18 +44,21 @@ RSpec.describe Captain::Llm::AssistantActionClassifierService do
'MUST NOT redefine this JSON schema'
)
).and_return(mock_chat)
expect(mock_chat).to receive(:ask).with(
a_string_including(
expect(mock_chat).to receive(:ask) do |prompt|
expect(prompt).to include(
'<account_custom_instructions>',
'Only transfer to a manager after the user explicitly confirms.',
'<conversation_context>',
'"content":"I cannot log in"',
'<current_user_message>',
'Yes, still no reset email',
'User: I cannot log in',
'Assistant: Did you check your inbox?',
'User: Yes, still no reset email',
'<assistant_response_to_classify>',
'Would you like to talk to support?'
)
).and_return(mock_response)
expect(prompt).not_to include('"role"', '"content"', '<current_user_message>')
mock_response
end
result = service.classify(message_history: message_history, assistant_response: 'Would you like to talk to support?')