Send Message
Visão Geral
O Send Message permite enviar mensagens de status intermediárias diretamente para o usuário durante execução de actions demoradas. Estas mensagens não entram no contexto do LLM como histórico, servindo apenas para feedback em tempo real.
⚠️ Características Importantes
- 📱 Exclusivo API v2: Funciona apenas com processos assíncronos
- 🚫 Não contextual: Mensagens não vão para o histórico do LLM
- ⚡ Tempo real: Enviadas imediatamente via webhook
- 📊 Status intermediário: Role
assistantcom statusstatus_update
Diferença Fundamental
| Tipo | Contexto LLM | Propósito | Status Webhook |
|---|---|---|---|
| Send Message | ❌ Não entra | Feedback intermediário | status_update |
| ResponseToUser | ✅ Entra como histórico | Resposta contextual | done |
| ResponseToAgent | ✅ Entra como histórico | Instrução para LLM | - |
📤 Método Principal
send_status_message(message, metadata=None)
Envia mensagem de status intermediária para o usuário durante execução da action.
Parâmetros:
message(str): Obrigatório - Mensagem a ser enviada ao usuáriometadata(Dict): Metadados adicionais (opcional)
Quando utilizar:
- Actions que fazem chamadas demoradas para APIs externas
- Processamentos que levam vários segundos
- Etapas intermediárias de workflows complexos
- Indicar progresso de operações longas
Resultado esperado:
- Webhook imediato com
status: "status_update" - Mensagem exibida ao usuário em tempo real
- Não afeta o contexto do LLM
Exemplo básico:
def processo_demorado():
# Status inicial
actions_sdk.send_status_message("Iniciando processamento...")
# Etapa 1
api_result = call_external_api()
# Status intermediário
actions_sdk.send_status_message("Processando dados recebidos...")
# Etapa 2
processed_data = complex_processing(api_result)
# Status final antes da resposta
actions_sdk.send_status_message("Finalizando...")
# Resposta principal (vai para contexto do LLM)
return actions_sdk.ResponseToUser(
status=actions_sdk.ResponseStatus.SUCCESS,
message="Processamento concluído com sucesso!",
instruction="Dados processados e resultado entregue ao usuário"
)
🎯 Fluxo de Webhooks
Exemplo Prático: Geração de Nome Pirata
Com base no exemplo fornecido, vamos analisar o fluxo completo:
def gerar_nome_pirata(name: str):
# 1. Status inicial
actions_sdk.send_status_message("gerando nome pirata")
# 2. Processamento demorado (LLM call)
llm_result = llm_helper.completion(
system_prompt=system_prompt,
user_prompt=user_prompt,
response_format=pirate_response_schema,
temperature=0.8
)
# 3. Status final antes da resposta
actions_sdk.send_status_message("nome pirata gerado")
# 4. Resposta principal
return actions_sdk.ResponseToAgent(
status=actions_sdk.ResponseStatus.SUCCESS,
instruction=f"Nome pirata gerado com sucesso para {name}",
# ... resto dos dados
)
Sequência de Webhooks Gerados
1️⃣ Primeiro Webhook - Status Inicial
{
"session_id": "6cf61e0e-05b0-4d53-a2ee-1c25b4907459",
"status": "status_update",
"detail": "Action status message",
"relation_message_ids": ["fbc7aca3-7269-4f26-8ca5-67cfafd4a69b"],
"response": {
"role": "assistant",
"content": [
{
"type": "text",
"text": {
"body": "gerando nome pirata"
}
}
]
}
}
2️⃣ Segundo Webhook - Status Intermediário
{
"session_id": "6cf61e0e-05b0-4d53-a2ee-1c25b4907459",
"status": "status_update",
"detail": "Action status message",
"relation_message_ids": ["103bebb4-6d28-48c1-b396-e355888ce74d"],
"response": {
"role": "assistant",
"content": [
{
"type": "text",
"text": {
"body": "nome pirata gerado"
}
}
]
}
}
3️⃣ Terceiro Webhook - Resposta Final
{
"session_id": "6cf61e0e-05b0-4d53-a2ee-1c25b4907459",
"status": "done",
"detail": "response generated successfully",
"relation_message_ids": ["9c744cb1-903e-4e8c-bcf7-d4d3ea4d1c66"],
"metadata": {
"topic": "Gerar Nome Pirata"
},
"response": {
"role": "assistant",
"content": [
{
"type": "text",
"text": {
"body": "Ahoy, marujo! O nome pirata que eu criei para ti é: Ruy dos Mares, o Tempestuoso!\n\nSe não gostares, posso gerar mais opções. O que dizes?"
}
}
]
}
}
💡 Casos de Uso Recomendados
✅ Processamento de Documentos
def validar_documento(document_url: str):
actions_sdk.send_status_message("🔍 Analisando documento...")
# Upload do arquivo
file_id = actions_sdk.upload_file(document_url)
actions_sdk.send_status_message("📄 Extraindo informações...")
# Extração de dados com OCR
extracted_data = ocr_service.extract_text(file_id)
actions_sdk.send_status_message("✅ Validando dados...")
# Validação dos dados
validation_result = validate_document_data(extracted_data)
actions_sdk.send_status_message("📋 Processamento concluído!")
return actions_sdk.ResponseToUser(
status=actions_sdk.ResponseStatus.SUCCESS,
message=f"Documento validado: {validation_result.status}",
instruction="Documento processado e validado com sucesso"
)
✅ Integração com APIs Externas
def buscar_informacoes_cpf(cpf: str):
actions_sdk.send_status_message("🔍 Consultando CPF na Receita Federal...")
# Primeira consulta
receita_data = receita_api.consultar_cpf(cpf)
actions_sdk.send_status_message("📊 Buscando dados complementares...")
# Segunda consulta
serasa_data = serasa_api.consultar_cpf(cpf)
actions_sdk.send_status_message("🔄 Consolidando informações...")
# Consolidação
consolidated_data = consolidate_data(receita_data, serasa_data)
actions_sdk.send_status_message("✅ Consulta finalizada!")
return actions_sdk.ResponseToUser(
status=actions_sdk.ResponseStatus.SUCCESS,
message=f"Dados do CPF {cpf} consolidados com sucesso!",
instruction="Consulta de CPF realizada em múltiplas bases"
)
✅ Workflows Multi-etapas
def processo_onboarding(user_data: dict):
total_steps = 5
# Etapa 1
actions_sdk.send_status_message(f"📋 Iniciando onboarding (1/{total_steps})")
validate_user_data(user_data)
# Etapa 2
actions_sdk.send_status_message(f"🏦 Criando conta bancária (2/{total_steps})")
account = create_bank_account(user_data)
# Etapa 3
actions_sdk.send_status_message(f"💳 Gerando cartão (3/{total_steps})")
card = generate_card(account.id)
# Etapa 4
actions_sdk.send_status_message(f"📧 Enviando documentos (4/{total_steps})")
send_documents_email(user_data.email, account, card)
# Etapa 5
actions_sdk.send_status_message(f"✅ Onboarding concluído! (5/{total_steps})")
return actions_sdk.ResponseToUser(
status=actions_sdk.ResponseStatus.SUCCESS,
message="🎉 Onboarding realizado com sucesso! Verifique seu email.",
instruction="Processo de onboarding completo - conta e cartão criados"
)
⚠️ Considerações Importantes
Limitações da API v1
- Não funciona: API v1 não suporta webhooks assíncronos
- Use apenas: Em implementações com API v2
- Erro silencioso: Pode falhar silenciosamente em v1
Boas Práticas
# ✅ Bom - Mensagens descritivas e progressivas
actions_sdk.send_status_message("🔍 Analisando documento (1/3)")
actions_sdk.send_status_message("📊 Extraindo dados (2/3)")
actions_sdk.send_status_message("✅ Validação concluída (3/3)")
# ❌ Evitar - Mensagens genéricas
actions_sdk.send_status_message("Processando...")
actions_sdk.send_status_message("Processando...")
# ✅ Bom - Indicar contexto e progresso
actions_sdk.send_status_message("📄 Extraindo texto do PDF...")
# ❌ Evitar - Informações que deveriam estar no contexto LLM
actions_sdk.send_status_message("Seu CPF é válido") # Use ResponseToUser
# ✅ Bom - Com metadados para tracking
actions_sdk.send_status_message(
"Validando documento...",
metadata={"document_type": "RG", "step": 2}
)
Diferença Crítica: Status vs Contexto
# ❌ ERRADO - Informação contextual em status message
actions_sdk.send_status_message("Seu saldo atual é R$ 1.500,00")
# Esta informação deveria estar no ResponseToUser para o LLM saber
# ✅ CORRETO - Status message apenas para feedback
actions_sdk.send_status_message("💰 Consultando saldo...")
# Depois retornar saldo no ResponseToUser/ResponseToAgent
return actions_sdk.ResponseToUser(
message="Seu saldo atual é R$ 1.500,00",
instruction="Saldo consultado e exibido para o usuário"
)
O Send Message funciona apenas com API v2 e processos assíncronos. Em API v1, as chamadas podem falhar silenciosamente.
Use Send Message para feedback em tempo real, não para informações que o LLM precisa conhecer. Para dados contextuais, use ResponseToUser/ResponseToAgent.
O Send Message é essencial para manter o usuário informado durante processos longos, mas lembre-se: status ≠ contexto. Use para feedback, não para informações que o LLM precisa conhecer!