Import ClientFlow production v4928.1.5.132.4
This commit is contained in:
@@ -254,6 +254,28 @@ def mark_raw_event_processed(
|
||||
})
|
||||
|
||||
|
||||
def mark_raw_event_error(raw_event_id: str, error: str) -> None:
|
||||
"""Regista erro de processamento sem marcar o evento como processado.
|
||||
|
||||
Isto evita filas silenciosas: o evento deixa de ficar em
|
||||
processed=false/ignored=false/processing_error=null, mas continua elegível
|
||||
para recovery explícito com scripts administrativos.
|
||||
"""
|
||||
with engine.begin() as conn:
|
||||
conn.execute(text("""
|
||||
UPDATE raw_events
|
||||
SET
|
||||
processed = FALSE,
|
||||
ignored = FALSE,
|
||||
processing_error = :error,
|
||||
processed_at = now()
|
||||
WHERE id = CAST(:raw_event_id AS UUID)
|
||||
"""), {
|
||||
"raw_event_id": raw_event_id,
|
||||
"error": str(error or "processing_exception")[:1000],
|
||||
})
|
||||
|
||||
|
||||
def get_state_for_conversation(conversation_id: str | None) -> CurrentState:
|
||||
if not conversation_id:
|
||||
return CurrentState()
|
||||
@@ -288,3 +310,52 @@ def get_state_for_conversation(conversation_id: str | None) -> CurrentState:
|
||||
"last_created_at": str(row.get("created_at")),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def get_recent_chatwoot_public_context(
|
||||
conversation_id: str | None,
|
||||
*,
|
||||
current_source_event_id: str | None = None,
|
||||
max_messages: int = 2,
|
||||
) -> list[str]:
|
||||
"""Devolve as últimas mensagens públicas Chatwoot para contexto LLM.
|
||||
|
||||
Usado quando o webhook não traz `conversation.messages`. Lê raw_events já
|
||||
guardados e exclui a mensagem atual para evitar que o LLM confunda histórico
|
||||
com o email recebido agora.
|
||||
"""
|
||||
if not conversation_id:
|
||||
return []
|
||||
|
||||
with engine.begin() as conn:
|
||||
rows = conn.execute(text("""
|
||||
SELECT
|
||||
source_event_id,
|
||||
payload #>> '{message_type}' AS message_type,
|
||||
payload #>> '{content}' AS content,
|
||||
created_at
|
||||
FROM raw_events
|
||||
WHERE source_system = 'chatwoot'
|
||||
AND event_type = 'message_created'
|
||||
AND conversation_id = :conversation_id
|
||||
AND COALESCE(payload #>> '{content}', '') <> ''
|
||||
AND (CAST(:current_source_event_id AS TEXT) IS NULL OR source_event_id <> CAST(:current_source_event_id AS TEXT))
|
||||
AND COALESCE(payload #>> '{private}', 'false') <> 'true'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT :limit
|
||||
"""), {
|
||||
"conversation_id": str(conversation_id),
|
||||
"current_source_event_id": str(current_source_event_id or "") or None,
|
||||
"limit": max(1, int(max_messages or 2)),
|
||||
}).mappings().all()
|
||||
|
||||
lines: list[str] = []
|
||||
for row in reversed(rows):
|
||||
role = "BLIF" if str(row.get("message_type") or "").lower() == "outgoing" else "Cliente"
|
||||
content = str(row.get("content") or "")
|
||||
content = " ".join(content.split())
|
||||
if len(content) > 360:
|
||||
content = content[:359].rstrip() + "…"
|
||||
if content:
|
||||
lines.append(f"- {role}: {content}")
|
||||
return lines
|
||||
|
||||
Reference in New Issue
Block a user