fix(captain/hermes-builder): callback resolve session via last_session
Bug: Hermes nao propaga chat_id no metadata do callback. Callback controller nao conseguia resolver qual session armazenar a resposta. WARN "no session_key resolvable — ignorando" descartava todas as respostas do Construtor. Fix: HermesBuilder::Storage.remember_last_session() grava ultima session por account quando admin chama /start ou /create. Callback le essa key via last_session_for(account_id). MVP-safe pra 1 admin por conta. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f362949579
commit
5f6aed05c9
@ -30,35 +30,14 @@ class Webhooks::Captain::HermesBuilderCallbackController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
# Estratégia: usar o session_id do metadata (Hermes propaga o chat_id).
|
||||
# Fallback: account_id da query string + último user que mandou msg
|
||||
# (raro, mas evita perder resposta).
|
||||
# Hermes nao propaga chat_id no metadata da resposta de callback, entao
|
||||
# usamos a ultima sessao ativa do account (gravada por
|
||||
# HermesBuilder::Storage.remember_last_session no /start e /create).
|
||||
# MVP-safe pra 1 admin por vez por conta.
|
||||
def resolve_session_key
|
||||
chat_id = params[:metadata]&.[](:chat_id) || params.dig(:metadata, 'chat_id')
|
||||
if chat_id.is_a?(String) && chat_id.include?('builder-')
|
||||
# Formato: webhook:construtor-admin:session:builder-<account>-<user>
|
||||
session_id = chat_id.split(':').last
|
||||
return "hermes_builder:#{session_id}" if session_id.start_with?('builder-')
|
||||
end
|
||||
|
||||
account_id = params[:account_id]
|
||||
return nil if account_id.blank?
|
||||
|
||||
# Fallback: pega últimas 5 sessões do account, retorna a mais recente
|
||||
# com mensagens. Aceitável pra MVP com 1 admin testando por vez.
|
||||
recent_session_key_for(account_id)
|
||||
end
|
||||
|
||||
def recent_session_key_for(account_id)
|
||||
return nil unless Rails.cache.respond_to?(:redis)
|
||||
|
||||
pattern = "hermes_builder:builder-#{account_id}-*"
|
||||
keys = Rails.cache.redis.with { |c| c.keys(pattern) }
|
||||
return nil if keys.blank?
|
||||
|
||||
keys.first.sub(/^.*?(hermes_builder:.*)$/, '\1')
|
||||
rescue StandardError => e
|
||||
Rails.logger.warn("[HermesBuilder::Callback] recent_session_key fallback failed: #{e.class} - #{e.message}")
|
||||
nil
|
||||
HermesBuilder::Storage.last_session_for(account_id)
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,6 +21,7 @@ class Api::V1::Accounts::Captain::HermesBuilderController < Api::V1::Accounts::B
|
||||
return render json: { error: 'Texto vazio' }, status: :bad_request if text.blank?
|
||||
|
||||
HermesBuilder::Storage.append(session_key, role: 'user', content: text)
|
||||
HermesBuilder::Storage.remember_last_session(Current.account.id, session_key)
|
||||
HermesBuilder::Dispatcher.send_to_construtor(session_id: session_id, message: text)
|
||||
|
||||
render json: { ok: true, session_id: session_id }, status: :accepted
|
||||
@ -34,6 +35,7 @@ class Api::V1::Accounts::Captain::HermesBuilderController < Api::V1::Accounts::B
|
||||
# quando admin clica "Iniciar" — sem ter que digitar primeira msg.
|
||||
def start
|
||||
HermesBuilder::Storage.clear(session_key)
|
||||
HermesBuilder::Storage.remember_last_session(Current.account.id, session_key)
|
||||
HermesBuilder::Dispatcher.send_to_construtor(
|
||||
session_id: session_id,
|
||||
message: '__START__ Inicie o fluxo de criação de novo agente Hermes. Comece pela primeira pergunta do Bloco 1 (nome do agente).'
|
||||
|
||||
@ -29,4 +29,15 @@ module HermesBuilder::Storage
|
||||
def clear(session_key)
|
||||
Rails.cache.delete(session_key)
|
||||
end
|
||||
|
||||
# Última sessão ativa por account — usada pelo callback do Hermes pra
|
||||
# roteamento (Hermes nao propaga chat_id no metadata da resposta).
|
||||
# Aceitavel pra MVP com 1 admin por vez por conta.
|
||||
def remember_last_session(account_id, session_key)
|
||||
Rails.cache.write("hermes_builder:last_session:account:#{account_id}", session_key, expires_in: TTL)
|
||||
end
|
||||
|
||||
def last_session_for(account_id)
|
||||
Rails.cache.read("hermes_builder:last_session:account:#{account_id}")
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user