Resolve duas camadas de problema identificadas em teste end-to-end: 1. Embeddings falhavam com HTTP 404 (/codex/v1/embeddings não existe). Solução: Captain::Llm::EmbeddingService sempre usa OpenAI tradicional via Llm::Config.with_api_key(legacy_settings). ProviderConfig expõe legacy_openai_settings pra isso. 2. Servidor Codex ocasionalmente responde com response.failed + code=server_error (instabilidade transitória). Client agora retenta até 2x com backoff exponencial (0.5s, 1.5s) em erros retryable: HTTP 5xx, server_error no response.failed, ou stream inacabado. Outras correções nesta etapa: - Scenario#agent_model: em modo Codex, ignora CAPTAIN_OPEN_AI_MODEL_SCENARIO (que pode ter gpt-4o legado) e usa ProviderConfig.model. - ExtractionService/ContradictionCheckerService/TranslateQueryService: trocam constantes hardcoded gpt-4o-mini/gpt-4.1-nano por ProviderConfig.light_model (respeitando o provider ativo). - ProviderConfig.DEFAULT_CODEX_MODEL agora é gpt-5.2 (reconhecido pelo RubyLLM; gpt-5.4 não está no catalog do gem). Validado ponta-a-ponta: WhatsApp → Chatwoot → Jasmine → handoff Daniela → faq_lookup com embedding OK → resposta com preços corretos. Docs em docs/captain-codex-oauth.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.3 KiB
Ruby
52 lines
1.3 KiB
Ruby
class Captain::Llm::TranslateQueryService < Captain::BaseTaskService
|
|
def self.model
|
|
Captain::Llm::ProviderConfig.light_model
|
|
end
|
|
|
|
pattr_initialize [:account!]
|
|
|
|
def translate(query, target_language:)
|
|
return query if query_in_target_language?(query)
|
|
|
|
messages = [
|
|
{ role: 'system', content: system_prompt(target_language) },
|
|
{ role: 'user', content: query }
|
|
]
|
|
|
|
response = make_api_call(model: self.class.model, messages: messages)
|
|
return query if response[:error]
|
|
|
|
response[:message].strip
|
|
rescue StandardError => e
|
|
Rails.logger.warn "TranslateQueryService failed: #{e.message}, falling back to original query"
|
|
query
|
|
end
|
|
|
|
private
|
|
|
|
def event_name
|
|
'translate_query'
|
|
end
|
|
|
|
def query_in_target_language?(query)
|
|
detector = CLD3::NNetLanguageIdentifier.new(0, 1000)
|
|
result = detector.find_language(query)
|
|
|
|
result.reliable? && result.language == account_language_code
|
|
rescue StandardError
|
|
false
|
|
end
|
|
|
|
def account_language_code
|
|
account.locale&.split('_')&.first
|
|
end
|
|
|
|
def system_prompt(target_language)
|
|
<<~SYSTEM_PROMPT_MESSAGE
|
|
You are a helpful assistant that translates queries from one language to another.
|
|
Translate the query to #{target_language}.
|
|
Return just the translated query, no other text.
|
|
SYSTEM_PROMPT_MESSAGE
|
|
end
|
|
end
|