Pular para conteúdo

API: Agents

Visão Geral

Gerenciamento de agentes IA que processam conversas. Cada agente possui um system prompt, mensagens customizáveis e base de conhecimento.

Endpoints

GET /api/agents

Lista todos os agentes do tenant.

Response (200 OK):

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Suporte TI",
    "isActive": true,
    "createdAt": "2024-01-15T10:30:00Z",
    "todayConversations": 12
  }
]


GET /api/agents/{id}

Retorna detalhes de um agente.

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Suporte TI",
  "description": "Agente para suporte técnico interno",
  "systemPrompt": "Você é um assistente de TI...",
  "isActive": true,
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-20T14:00:00Z",
  "totalConversations": 150,
  "todayConversations": 12
}


POST /api/agents

Cria um novo agente.

Request:

{
  "name": "Suporte TI",
  "description": "Agente para suporte técnico interno",
  "systemPrompt": "Você é um assistente de TI especializado...",
  "isActive": true
}

Response (201 Created):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Suporte TI"
}


PUT /api/agents/{id}

Atualiza um agente.

Request:

{
  "name": "Suporte TI v2",
  "description": "Agente atualizado",
  "systemPrompt": "Você é um assistente de TI...",
  "isActive": true
}

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Suporte TI v2"
}


DELETE /api/agents/{id}

Remove um agente.

Response: 204 No Content


Sub-recursos

Mensagens Customizadas

GET /api/agents/{agentId}/messages

Retorna as mensagens customizadas do agente.

Response (200 OK):

{
  "errorMessage": "Desculpe, estou com dificuldades técnicas.",
  "welcomeMessage": "Olá! Como posso ajudar?",
  "rateLimitMessage": "Você está enviando muitas mensagens.",
  "outOfHoursMessage": "Nosso atendimento funciona das 8h às 18h."
}

PUT /api/agents/{agentId}/messages

Atualiza as mensagens customizadas.

Request:

{
  "errorMessage": "Desculpe, tente novamente.",
  "welcomeMessage": "Bem-vindo!",
  "rateLimitMessage": null,
  "outOfHoursMessage": null
}


Base de Conhecimento

GET /api/agents/{agentId}/knowledge

Lista blocos de conhecimento do agente.

Response (200 OK):

[
  {
    "id": "660e8400-e29b-41d4-a716-446655440000",
    "title": "Impressoras",
    "content": "## Problemas comuns\n\n- Papel atolado...",
    "displayOrder": 0,
    "isActive": true,
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
]

GET /api/agents/{agentId}/knowledge/{id}

Retorna um bloco específico.

POST /api/agents/{agentId}/knowledge

Cria um bloco de conhecimento.

Request:

{
  "title": "Impressoras",
  "content": "## Problemas comuns\n\n- Papel atolado...",
  "displayOrder": 0,
  "isActive": true
}

PUT /api/agents/{agentId}/knowledge/{id}

Atualiza um bloco.

DELETE /api/agents/{agentId}/knowledge/{id}

Remove um bloco.

POST /api/agents/{agentId}/knowledge/reorder

Reordena os blocos.

Request:

{
  "orderedIds": [
    "660e8400-e29b-41d4-a716-446655440000",
    "770e8400-e29b-41d4-a716-446655440001"
  ]
}


FAQ (Perguntas Frequentes)

FAQs são pares pergunta/resposta que participam da busca semântica junto com a base de conhecimento.

GET /api/agents/{agentId}/faq

Lista FAQs do agente.

Response (200 OK):

[
  {
    "id": "990e8400-e29b-41d4-a716-446655440000",
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "question": "Qual o horário de funcionamento?",
    "answer": "Funcionamos de segunda a sexta, das 9h às 18h.",
    "displayOrder": 0,
    "isActive": true,
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
]

GET /api/agents/{agentId}/faq/{id}

Retorna uma FAQ específica.

POST /api/agents/{agentId}/faq

Cria uma FAQ. O embedding é gerado automaticamente.

Request:

{
  "question": "Qual o horário de funcionamento?",
  "answer": "Funcionamos de segunda a sexta, das 9h às 18h.",
  "isActive": true
}

Response (201 Created):

{
  "id": "990e8400-e29b-41d4-a716-446655440000",
  "agentId": "550e8400-e29b-41d4-a716-446655440000",
  "question": "Qual o horário de funcionamento?",
  "answer": "Funcionamos de segunda a sexta, das 9h às 18h.",
  "displayOrder": 0,
  "isActive": true,
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

PUT /api/agents/{agentId}/faq/{id}

Atualiza uma FAQ. Se pergunta ou resposta mudarem, o embedding é regenerado.

Request:

{
  "question": "Qual o horário de atendimento?",
  "answer": "Funcionamos de segunda a sexta, das 9h às 18h, e sábados das 9h às 13h.",
  "isActive": true
}

DELETE /api/agents/{agentId}/faq/{id}

Remove uma FAQ.

Response: 204 No Content

POST /api/agents/{agentId}/faq/reorder

Reordena as FAQs.

Request:

{
  "orderedIds": [
    "990e8400-e29b-41d4-a716-446655440000",
    "aa0e8400-e29b-41d4-a716-446655440001"
  ]
}


Configurações de IA

Controle o comportamento da IA: tom, idioma e emojis.

Nota: Campos como showTyping, delaySeconds, signatureText e signaturePosition foram movidos para a entidade WhatsAppInstance (configurados na aba "Configurações" da instância).

GET /api/agents/{agentId}/ai-settings

Retorna as configurações de IA do agente.

Response (200 OK):

{
  "tone": "Professional",
  "language": "PtBr",
  "allowEmojis": true
}

PUT /api/agents/{agentId}/ai-settings

Atualiza as configurações de IA.

Request:

{
  "tone": "Friendly",
  "language": "PtBr",
  "allowEmojis": true
}

Campos:

Campo Tipo Descrição Default
tone AgentTone Tom de comunicação Professional
language AgentLanguage Idioma das respostas PtBr
allowEmojis bool Permite emojis nas respostas true

Enums:

  • AgentTone: Formal, Professional, Friendly
  • AgentLanguage: PtBr, PtPt, En, Es

Etapas de Atendimento

Etapas guiam a IA por um fluxo estruturado de atendimento. Sem etapas, o agente responde livremente.

GET /api/agents/{agentId}/steps

Lista etapas do agente ordenadas por posição.

Response (200 OK):

[
  {
    "id": "aa0e8400-e29b-41d4-a716-446655440000",
    "name": "Saudação",
    "instructions": "Cumprimente o cliente e pergunte como pode ajudar...",
    "optimizedInstructions": null,
    "order": 1,
    "isActive": true,
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
]

POST /api/agents/{agentId}/steps

Cria uma nova etapa. Instruções são otimizadas automaticamente.

Request:

{
  "name": "Coleta do Pedido",
  "instructions": "Pergunte ao cliente o que deseja pedir..."
}

Response (201 Created):

{
  "id": "bb0e8400-e29b-41d4-a716-446655440001",
  "name": "Coleta do Pedido",
  "order": 2
}

PUT /api/agents/{agentId}/steps/{id}

Atualiza uma etapa. Re-otimiza se as instruções mudaram.

Request:

{
  "name": "Coleta do Pedido",
  "instructions": "Pergunte ao cliente o que deseja pedir. Confirme cada item."
}

DELETE /api/agents/{agentId}/steps/{id}

Remove uma etapa. Conversas ativas nesta etapa terão CurrentStepId limpo.

Response: 204 No Content

PUT /api/agents/{agentId}/steps/reorder

Reordena as etapas.

Request:

{
  "stepIds": [
    "bb0e8400-e29b-41d4-a716-446655440001",
    "aa0e8400-e29b-41d4-a716-446655440000"
  ]
}

PUT /api/agents/{agentId}/steps/{id}/toggle

Ativa/desativa uma etapa.


Validações de Etapas

Campo Regra
Name Obrigatório, máx 100 caracteres
Instructions Obrigatório, máx 20000 caracteres

Playground

Endpoints para testar o agente diretamente pelo portal administrativo. Todos os endpoints do playground: - Requerem autorização Admin (RequireAuthorization(AuthConstants.Roles.Admin)) - Estão sob rate limiting LLM (RequireRateLimiting(RateLimitPolicies.Llm)) - Upload de mídia para R2 é feito em paralelo com o processamento via PlaygroundMediaHelper

POST /api/agents/{agentId}/playground/chat

Envia mensagens de teste para o agente. Suporta texto e imagens (Claude Vision).

Request:

{
  "messages": [
    {
      "role": "user",
      "content": "Olá",
      "type": "text"
    },
    {
      "role": "assistant",
      "content": "Olá! Como posso ajudar?",
      "type": "text"
    },
    {
      "role": "user",
      "content": "O que tem nesta imagem?",
      "type": "image",
      "mediaBase64": "iVBORw0KGgo...",
      "mediaMimeType": "image/jpeg"
    }
  ]
}

Campos da mensagem (PlaygroundMessageDto):

Campo Tipo Descrição
role string "user" ou "assistant"
content string Texto da mensagem (ou legenda da imagem)
type string "text" (padrão) ou "image"
mediaBase64 string? Dados da imagem em base64 (apenas type="image")
mediaMimeType string? MIME type da mídia (ex: "image/jpeg")

Response (200 OK):

{
  "content": "Na imagem posso ver...",
  "inputTokens": 1500,
  "outputTokens": 200
}

Comportamento: - Mensagens de texto são enviadas normalmente ao LLM - Mensagens de imagem são convertidas para ChatMessage.WithImage() (Claude Vision multimodal) - Limitado às últimas 20 mensagens do histórico


POST /api/agents/{agentId}/playground/transcribe

Transcreve áudio em texto usando Whisper (OpenAI).

Request:

{
  "audioBase64": "UklGRiQA...",
  "mimeType": "audio/webm"
}

Campo Tipo Descrição
audioBase64 string Áudio gravado em base64
mimeType string MIME type do áudio (ex: "audio/webm", "audio/ogg")

Response (200 OK):

{
  "text": "Como configuro uma impressora?"
}

Comportamento: - Converte base64 para bytes e envia ao Whisper API - Retorna texto transcrito que o frontend usa como mensagem de texto - Validação: audioBase64 e mimeType são obrigatórios


POST /api/agents/{agentId}/playground/describe-image

Realiza OCR/descrição de imagem via Claude Vision. O frontend usa o texto retornado como contexto antes de enviar ao LLM no chat.

Request:

{
  "imageBase64": "iVBORw0KGgo...",
  "mimeType": "image/jpeg",
  "caption": "O que é isso?"
}

Campo Tipo Descrição
imageBase64 string Dados da imagem em base64
mimeType string MIME type da imagem (ex: "image/jpeg", "image/png")
caption string? Legenda opcional da imagem

Response (200 OK):

{
  "description": "Uma foto de uma pizza margherita em uma caixa de papelão branca...",
  "mediaUrl": "https://r2.example.com/tenants/.../playground/image.jpeg"
}

Campo Tipo Descrição
description string Texto descritivo gerado pelo Claude Vision
mediaUrl string? URL da imagem salva no R2 (pode ser null se upload falhar)

Comportamento: - OCR via Claude Vision e upload para R2 executam em paralelo (Task.WhenAll) - Se o upload falhar, o processamento continua e mediaUrl retorna null - Se a descrição falhar, retorna erro 400 com mensagem de validação - Handler: PlaygroundDescribeImageHandler


Validações

CreateAgentRequest / UpdateAgentRequest

Campo Regra
Name Obrigatório, máx 100 caracteres
SystemPrompt Obrigatório

CreateKnowledgeBlockRequest

Campo Regra
Title Obrigatório, máx 200 caracteres
Content Obrigatório

CreateFaqItemRequest / UpdateFaqItemRequest

Campo Regra
Question Obrigatório, máx 500 caracteres
Answer Obrigatório

UpdateAgentAiSettingsRequest

Campo Regra
tone Enum válido (AgentTone)
language Enum válido (AgentLanguage)

Erros Comuns

Status Código Descrição
404 AGENT_NOT_FOUND Agente não encontrado
409 AGENT_NAME_EXISTS Já existe agente com este nome
400 VALIDATION_ERROR Campos inválidos