Rylvo
Crie, execute e gerencie agentes de IA no seu espaço de trabalho Rylvo: bots, prompts, proteções, bases de conhecimento, canais, testes e fluxos.
Servidor MCP hospedado
npx add-mcp 'https://rylvo.com/mcp'Instala no Claude Code, Codex, Cursor e outros
Documentação
Referência da API Rylvo
Um único endpoint. Controle agêntico completo. Execute uma interação do bot — prompts, guardrails, ferramentas e recuperação da base de conhecimento — com sua própria chave de LLM, em minutos.
Início Rápido
Faça sua primeira chamada de API em menos de um minuto. Você precisa de um botId e de uma chave de API do painel. As chaves de API estão incluídas a partir do plano Lite; workspaces Free e Starter não possuem nenhuma, e colocam um bot em um site com o widget ou o compartilham com um link Beam.
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"botId": "your_bot_id",
"sessionId": "session_001",
"message": "I can't access my account."
}'
Modelo de Acesso
A Rylvo expõe três superfícies. Saber qual usar para quê evita confusão ao integrar um backend, conectar um editor de IA ou operar a plataforma no dia a dia.
Convenção de caminho: os caminhos de documentos do Firestore nesta referência escrevem {envRoot} como abreviação para a raiz do workspace-ambiente — a subárvore environments/{environment} sob organizations/{orgId} — onde {environment} é production ou test. Coleções de propriedade do ambiente existem de forma independente por ambiente — o mesmo ID lógico em Teste e Produção refere-se a dois documentos diferentes. Dados de todo o workspace (membros, cobrança, log de auditoria) permanecem diretamente sob organizations/{orgId}.
REST PúblicoTempo de execução do backend
Chame a partir do seu backend com a chave de API da sua organização (Authorization: Bearer rylv_…). Esta é a superfície de tempo de execução que você envia para produção.
POST /api/v1/bot-run(escopo: responder)POST /api/v1/kb/query(escopo: kb:read)POST /api/v1/kb/documents(escopo: kb:write)POST /api/v1/tests/gate(escopo: tests:read)/health,/ready,/live,/flags(não autenticados)
MCP / Editor de IAFerramentas externas de IA
Conecte Claude Code, Cursor, Windsurf, Zed ou Codex diretamente à Rylvo. OAuth 2.1 + PKCE, tokens com escopo da organização.
POST /mcp(Streamable HTTP)- Registro
/oauth/*+ troca de tokens - 167 ferramentas para bots, prompts, KB, skills, conectores
- Especificação OpenAPI 3.1 dos 3 endpoints REST públicos em
/openapi.json
PainelConfiguração e operações
Gerencie em rylvo.com/dashboard. Muitos recursos também são acessíveis pela superfície MCP / Editor de IA.
- Bots, Prompts, Guardrails, Base de Conhecimento
- Workspace Architect, Bot Chat, Bot Tests
- Edge Cases, Red Team, Automation, Reports
- Mission Control, Agent Evolution, Skills, MCP Hub
- Billing, Team, API Keys, Build Intelligence
As seções abaixo marcadas como Somente painel ainda não possuem um endpoint REST público dedicado. Elas permanecem totalmente funcionais dentro do painel, pela superfície MCP / Editor de IA, e seu comportamento afeta o tempo de execução /api/v1/bot-run.
Ambientes e Versões
Todo workspace possui dois ambientes: Teste e Produção. Você constrói e experimenta em Teste e, em seguida, promove uma versão congelada e versionada para Produção. Configuração, dados, análises, rastreamentos e chaves de API são isolados por ambiente — o mesmo ID lógico em Teste e Produção refere-se a dois documentos diferentes (veja Modelo de Acesso para a convenção de caminho {envRoot}). Há uma visão geral dedicada de Ambientes e Versões se você quiser o tour do produto.
Testeeditável
Uma cópia totalmente editável do seu workspace. Itere em bots, prompts, guardrails, fluxos, skills, conhecimento e conectores com modelos reais. O tráfego de Teste nunca toca a configuração ou os dados de Produção.
Produçãosomente leitura
O que seus clientes acessam. A configuração promovível é somente leitura — ela só muda quando você ativa uma versão ou a reverte. Uma organização que nunca promoveu continua servindo sua configuração legada até que a primeira versão seja ativada.
O ciclo de vida da versão
- Congele um candidato — capture a configuração atual de Teste em um candidato a versão imutável (um manifesto versionado de artefatos). Teste permanece editável.
- Revise o diff e os portões — veja o que mudou em relação à Produção ativa (adicionado / alterado / removido / inalterado, agrupado por família de artefatos). Portões opcionais: aprovação de duas pessoas (o criador não pode aprovar seu próprio manifesto) e uma execução de teste bem-sucedida.
- Ative a Produção — o ponteiro ativo alterna atomicamente, mas somente após cada artefato no manifesto ser verificado. A geração do ambiente é incrementada em um.
- Reverta se necessário — toda versão ativada é imutável e retida. Aponte a Produção de volta para qualquer versão anterior e o tráfego de tempo de execução alterna imediatamente.
Você também pode atualizar Teste a partir da versão ativa de Produção (o modo seguro preserva edições divergentes de Teste) ou redefinir Teste completamente. Toda operação destrutiva é verificada primeiro. Gerenciar versões (congelar, ativar, reverter) requer uma função de administrador ou proprietário.
Selecionando um ambiente pela API
Envie o cabeçalho X-Rylvo-Environment para escolher o ambiente de uma solicitação. Seu valor é production ou test. As chaves de API também têm escopo por ambiente, portanto, uma chave de Teste nunca pode autenticar contra dados de Produção. O mesmo bot responde com a configuração correta e grava no armazenamento de dados correto para o ambiente selecionado.
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Authorization: Bearer rylv_…" \
-H "X-Rylvo-Environment: test" \
-H "Content-Type: application/json" \
-d '{"botId": "…", "message": "hello"}'
Omitir o cabeçalho usa Produção por padrão. Veja Autenticação e Chaves de API para saber como as chaves são definidas por escopo.
Marca d'água de dados de Teste
Os dados exportados de Teste recebem marca d'água para que um conjunto de dados de Teste nunca seja confundido com registros reais de clientes downstream. As exportações de Produção não possuem marca d'água; as exportações de Teste sempre possuem, e a proveniência do ambiente viaja com os dados depois que eles saem da Rylvo.
Autenticação
Todas as solicitações de API exigem uma chave de API enviada no cabeçalho X-API-Key. Crie chaves no seu painel.
X-API-Key: rylv_abc123...
Segurança: nunca exponha chaves de API em código do lado do cliente. Sempre chame a API a partir do seu backend.
BotsSomente painel
Todo agente no seu workspace é construído, configurado e enviado a partir de Painel → Bots. A barra lateral lista os grupos de agentes primeiro e os bots independentes depois, cada um mostrando o modelo em que executa e se está ativo.
Novo Bot — do zero
- Nome, avatar gerado e uma descrição da finalidade do agente
- Modelo, escolhido uma vez entre todos os provedores para os quais você possui uma chave (veja BYOK abaixo)
- Alternâncias de entrada de imagem e áudio
- Quantas mensagens recentes o bot relê a cada interação
- Opcionalmente, coloque o novo agente diretamente em um grupo
De um modelo
- Catálogo de blueprints validados, pesquisáveis e filtráveis por categoria
- Bots de agente único primeiro, pipelines multiagente depois
- Escolher um abre uma etapa de personalização — nada é criado até você concluí-la
- O que você obtém é um bot totalmente editável, não um preset bloqueado
Um bot só é acessível pela API quando está ativo e você possui uma chave de provedor para o modelo dele. Agrupe vários bots para que eles possam passar trabalho uns aos outros — veja Grupos de Agentes.
Chaves de Provedor (BYOK)Somente painel
Cada chat de bot na Rylvo executa com sua própria chave de provedor de LLM. A Rylvo roteia a chamada no lado do servidor e registra um rastreamento completo para observabilidade, mas adiciona zero margem nos custos de tokens — você paga seu provedor de LLM diretamente. Gerencie as chaves em Configurações → Chaves de Provedor de LLM.
Bot Chat, Group Chat, Bot Tests
Roteia para a chave de provedor do cliente. Exige a chave direta correspondente do provedor (por exemplo, Anthropic para modelos anthropic/*) ou uma chave universal OpenRouter. Sem uma chave, a interface bloqueia o chat e exibe uma chamada para ação. Novos workspaces começam com uma chave de teste de 14 dias com US$ 2 de uso de IA, para que possam conversar antes de adicionar uma.
Workspace Architect
Executa com sua própria chave de provedor como todo o resto. Durante o teste Pro de 14 dias, ele executa com os US$ 2 de uso de IA incluídos pela Rylvo, para que você possa construir antes de adicionar uma chave. Os bots que ele cria também precisam de uma chave quando o teste termina.
Ordem de resolução de chaves
- Auto (padrão) — a chave nativa do provedor do modelo quando adicionada (direta, por exemplo,
api.anthropic.com), caso contrário, sua chave OpenRouter. - Sempre OpenRouter — todo chat executa com sua chave OpenRouter, mesmo quando uma chave direta existe.
- Somente chaves nativas — OpenRouter nunca é usado; modelos sem chave direta ficam bloqueados.
- Substituição por bot disponível no Bot Hub. Quando nenhuma chave pode atender a um modelo, a interface do chat nomeia exatamente quais chaves o desbloqueariam.
Provedores suportados
- OpenRouter — universal, cobre todos os modelos exceto Groq e GLM 4.7 FlashX
- OpenAI —
openai/* - Anthropic —
anthropic/*(adaptador nativo da Messages API) - Google Gemini —
google/*(adaptador nativogenerateContent) - DeepSeek —
deepseek/* - xAI (Grok) —
x-ai/* - Kimi / Qwen / GLM —
moonshotai/*,qwen/*,z-ai/*(bots mais antigos:kimi/*,zhipu/*); chaves de qualquer região funcionam - Mistral —
mistralai/* - Groq —
groq/*(precisa de chave própria; não está no OpenRouter) - MiniMax, Meta, Cohere, NVIDIA, Xiaomi, ByteDance, Tencent, StepFun, Inception, Upstage, IBM — somente chave OpenRouter
- A lista completa de modelos, com preços e a chave em que cada um executa, está no seletor de modelos do painel (Bots → Editar → Modelo).
Acesso e segurança
- Gravação/exclusão restrita aos administradores da organização.
- Leitura permitida para todos os membros da organização para que operadores possam conversar com bots.
- As chaves nunca saem do Firestore + do manipulador de rotas — nunca expostas ao HTML da página.
- A rotação de chaves redefine automaticamente o estado de verificação.
Verificada ao salvar
Toda chave é verificada com seu provedor antes de ser armazenada — um ping de 16 tokens (< US$ 0,001). Uma chave rejeitada pelo provedor nunca é salva, e a página mostra exatamente o que o provedor respondeu. Use Teste para verificar novamente uma chave salva a qualquer momento e Testar todas para verificar novamente todas as chaves de uma vez.
Marcação de Bots (Obrigatória)
Obrigatório: toda solicitação de tempo de execução deve incluir um botId (ou um groupId para um grupo de agentes). Solicitações sem nenhum dos dois são rejeitadas com um erro 400.
Os bots são a principal unidade organizacional para o uso da sua API. Cada bot representa um agente ou caso de uso distinto (por exemplo, "Bot de Triagem de Suporte", "Bot de Qualificação de Vendas"). Crie bots no seu painel e use o ID do bot para marcar cada chamada de API.
Como funciona
1
Crie um bot
Vá para Painel → Bots → Novo Bot. Dê a ele um nome e uma descrição.
2
Copie o ID do bot
Cada bot recebe um ID exclusivo. Copie-o do cartão do bot.
3
Marque toda solicitação de API
Inclua "botId": "seu_id_de_bot" no corpo da solicitação.
4
Veja análises por bot
Filtre rastreamentos, análises e cobrança por bot.
Exemplo de solicitação com botId
{
"botId": "bot_abc123def456",
"sessionId": "sess_001",
"message": "I can't access my account."
}
Benefícios da marcação de bots
Análises por bot
Veja métricas, latência e taxas de erro por bot
Agrupamento de rastreamentos
Filtre e pesquise rastreamentos por nome do bot
Associação de chaves
Vincule chaves de API a bots específicos
Controle de acesso
Gerencie permissões por bot
Bot Chat PlaygroundSomente painel
Teste o comportamento de um bot de ponta a ponta antes de apontar tráfego de produção para ele. O playground em /dashboard/bots/[botId]/chat monta o tempo de execução completo exatamente como /api/v1/bot-run faz: prompts de sistema, placeholders, guardrails, conectores, conexões de KB e regras de evolução.
Cada interação captura
- IDs de prompts ativos + placeholders resolvidos
- Guardrails avaliados (e quais foram acionados)
- Conectores invocados + corpos de solicitação/resposta
- Regras de evolução injetadas no prompt de sistema
- Etapa de fluxo ativa + transições avaliadas (se um fluxo estiver anexado)
- Uso de tokens + custo (executa com sua própria chave BYOK)
Bom para
- Reproduzir uma falha a partir de uma reprodução de rastreamento
- Iterar em um prompt antes de promovê-lo a ativo
- Verificar se um novo guardrail realmente é acionado
- Comparar dois bots lado a lado (
/dashboard/bots/[botId]/compare)
Cada interação do playground mostra a pilha de prompts, decisões de guardrails, chamadas de conectores, regras de evolução aplicadas, a etapa de fluxo ativa (se um fluxo estiver anexado), sussurros do operador, uso de tokens e custo — tudo junto com a própria mensagem.
Bot TestsSomente painel
Defina casos de teste reutilizáveis por bot e execute-os sob demanda ou por um agendamento de Automação. Gerencie em /dashboard/bots/[botId]/tests.
Um caso de teste especifica
- Mensagem de entrada (turno único) ou uma conversa multi-turno roteirizada
- Texto de saída esperado / comportamento
- Guardrails que devem ou não devem ser acionados
- Verificações nas respostas: palavras que devem ou nunca devem usar, um padrão, JSON de uma determinada forma, um número dentro de uma margem, texto próximo a uma resposta de referência
- Verificações sobre o que o bot fez: as ferramentas que chamou (ou que nunca deve chamar, ou em que ordem), se usou a base de conhecimento, a rapidez de cada resposta, o custo da conversa
- Pré-população opcional de
structured_state
Uma execução de teste produz
- Aprovado/reprovado por caso com diff em relação às expectativas
- Uso de tokens e custo de toda a execução
- Links de rastreamento completos para cada caso (para depuração)
- Um resumo que você pode anexar a um relatório ou canal de alerta
A forma como um teste é pontuado é sua. Testes → Pontuação define a nota de aprovação (70, a menos que você altere), critérios mais rígidos para uma prioridade ou tipo de teste, o que o avaliador de IA pontua e quanto cada parte conta — para todos os bots ou para um só. O teste reavalia a última execução do bot antes de você salvar, e cada execução registra a pontuação sob a qual foi avaliada, para que execuções com pontuações diferentes nunca sejam comparadas como se nada tivesse mudado. Todo plano pode ver isso; alterá-lo é recurso Pro, para administradores e proprietários.
Verificações são regras rígidas. Cada uma reprova o teste por conta própria, independentemente da pontuação do avaliador de IA, e uma verificação sem nada para ler — um tempo de resposta não registrado, um bot sem base de conhecimento — falha e informa isso em vez de passar silenciosamente. Similaridade compara a redação, não o significado: use-a quando uma frase exata for errada de se exigir, mas a resposta deva ser praticamente a mesma.
Uma falha vira um teste. Em um caso extremo, ou em qualquer resposta em Rastreamentos, "Adicionar como teste" abre o editor de testes já preenchido: as mensagens do cliente até o ponto em que deu errado, o que deveria ter acontecido e uma verificação que impede que passe novamente. Salve-o e o mesmo bug não pode ser lançado duas vezes — o caso extremo lista os testes criados a partir dele e os executa.
Conjuntos de testes mantêm uma suíte fixa. Salve os testes que importam — por exemplo, os que devem passar antes de um lançamento — como um conjunto nomeado. Cada versão congela uma cópia de cada teste contido nele, de modo que "a suíte de lançamento, versão 3" executa as mesmas conversas com as mesmas expectativas em março e em dezembro, independentemente de como os testes foram editados desde então. Cada versão marca quais de seus testes foram alterados ou excluídos desde então, e cada execução informa qual versão executou.
Testes viajam como arquivos. Baixe os testes de um bot, ou uma versão de um conjunto, como CSV (um teste por linha, para uma planilha), JSON Lines ou JSON — e importe qualquer um deles de volta. Uma importação é verificada antes que qualquer coisa seja adicionada, e um arquivo que não pode ser lido informa qual linha e por quê.
Até que ponto confiar no avaliador (Enterprise). Revisores dão seu próprio veredito sobre resultados avaliados — aprovado, parcial ou reprovado, e uma pontuação para qualquer parte, se quiserem. Testes → Pontuação mostra então com que frequência o avaliador de IA concorda com eles (com o kappa de Cohen, para que a concordância por acaso não conte), se ele é mais frequentemente generoso ou rigoroso demais e qual parte ele pontua mais distante dos seus revisores. Testar uma alteração de pontuação informa se o avaliador concordaria mais com eles, e um avaliador de linha de base fixado sinaliza qualquer execução avaliada de forma diferente — suas pontuações não se comparam com a tendência.
Um lançamento espera até que os testes passem. Ativado em Testes → Portão de lançamento, um lançamento para Produção espera até que todos os bots nele passem pelo portão em uma execução contra esse lançamento exato, e Revisar e lançar nomeia os testes que não passaram, cada um com um link para seu resultado. A menos que você altere, uma execução passa pelo portão quando nenhum de seus testes falha e pelo menos um passa. No Enterprise, você decide o que significa passar — uma taxa de aprovação, todos os testes críticos, uma execução de um conjunto de testes nomeado, a concordância do avaliador com seus revisores — e seu próprio pipeline de CI faz a mesma pergunta ao portão com POST /api/v1/tests/gate e uma chave de API com o escopo tests:read, reprovando o deploy a menos que ele diga "aprovado".
Casos de teste reprovados podem ser convertidos em Casos extremos para que o mecanismo os rastreie pelo loop detectar → classificar → corrigir → verificar.
Grupos de Agentes (Equipes Multi-Bot)Apenas no dashboard
Componha vários bots em uma equipe onde um bot roteia, delega e mescla resultados de especialistas. Útil para fluxos de trabalho que abrangem domínios (ex.: cobrança + suporte técnico) ou exigem rascunhos paralelos.
Modos de grupo
- Roteador — um bot escolhe o melhor especialista por turno
- Sequencial — os bots executam em um pipeline fixo
- Paralelo — os bots executam simultaneamente, um mesclador resume
- Round-robin — alterna os bots entre os turnos
Cada membro contribui
- Seus próprios prompts, guardrails, conectores e escopo de KB
- Uma função/persona anexada (ex.:
billing_specialist) - Seu próprio rastreamento — o rastreamento do grupo os vincula a todos
Os chats em grupo registram quais bots membros contribuíram para cada turno e como as decisões de roteamento foram tomadas, para que você possa depurar quem disse o quê e por quê.
Decisões tipadas em grupos: um roteador cujas regras leem apenas a intenção (sem outros fatos, sem pass_fields) é despachado por TypeSafe Jev; outros roteadores mantêm o classificador de LLM. Um fan-out com a mesclagem vote faz o Jev escolher o melhor ramo, e a resposta desse ramo é retornada exatamente como escrita — anteriormente, um LLM a redigitava. Ambos recorrem ao caminho de LLM se o Jev não puder responder.
Endpoints
| Método | Caminho | Descrição |
|---|---|---|
| POST | /api/v1/bot-run | Executa um turno de bot ou grupo de agentes (escopo: respond) |
| POST | /api/v1/kb/query | Consulta uma conexão de base de conhecimento (escopo: kb:read) |
| POST | /api/v1/kb/documents | Envia documentos para uma fonte de KB (escopo: kb:write) |
| POST | /api/v1/tests/gate | A execução de teste do bot passa pelo portão de lançamento? Para CI (escopo: tests:read) |
| GET | /health | Vitalidade (processo ativo) |
| GET | /ready | Prontidão (pode lidar com solicitações) |
| GET | /live | Sonda de uptime |
| GET | /flags | Sinalizadores de rollout |
O catálogo de modelos, rastreamentos, análises e CRUD de conectores são gerenciados pelo dashboard e pela superfície MCP / Editor de IA — eles não são expostos como endpoints REST públicos hoje.
Runtime (Turno do Bot)
POST /api/v1/bot-run é o núcleo do Rylvo. Envie uma mensagem (mais sessão e histórico opcionais) e o mecanismo executa um turno agêntico completo, retornando a resposta do assistente com telemetria completa. Ele é executado na sua própria chave BYOK.
Montagem do prompt
Prompts do bot + habilidades
Guardrails
Bloquear / reescrever / escalar
Ferramentas e conectores
Chamadas de ferramentas ao vivo
Recuperação de KB
Respostas fundamentadas
Formato da Solicitação
{
"botId": "bot_abc123def456",
"sessionId": "sess_001",
"message": "The display shows error E42.",
"conversationHistory": [
{ "role": "user", "content": "Hi, my device won't start." },
{ "role": "assistant", "content": "I can help. What does the screen show?" }
],
"endUserExternalId": "user_8842",
"endUserDisplayName": "Jordan Lee",
"channel": "api"
}
Campos Obrigatórios
| Campo | Tipo | Descrição |
|---|---|---|
| botId | string | Identificador do bot (do Dashboard → Bots). É necessário botId ou groupId. |
| message | string | A mensagem atual do usuário final |
Campos Opcionais
| Campo | Tipo | Descrição |
|---|---|---|
| groupId | string | ID do grupo de agentes (executa uma equipe multi-bot em vez de um único bot) |
| conversationHistory | object[] | Turnos anteriores: { role: 'user' | 'assistant', content } |
| sessionId | string | ID da conversa/sessão; ecoado de volta como conversationId |
| endUserExternalId | string | ID estável do usuário final no seu namespace (≤256). Obrigatório para nome de exibição / e-mail. |
| endUserDisplayName | string | Nome legível mostrado em Rastreamentos (≤200) |
| endUserEmail | string | E-mail do usuário final para transferência de suporte (validado) |
| known_facts | object[] | O que você já sabe sobre a pessoa: [{ key, value }], no máximo 20. key é uma chave de campo de Coleta de Dados do bot (minúscula, ≤64, enviada uma vez); value é texto ≤1000. Usado apenas para que o bot não pergunte novamente; nunca salvo; deve ser uma resposta válida para esse campo. Uma lista malformada resulta em 400. |
| channel | string | api (padrão) | widget | whatsapp | slack | unknown |
| model | string | Substituição de modelo (ex.: openai/gpt-4.1-mini, anthropic/claude-sonnet-4.6) |
| maxTokens | number | Máximo de tokens de saída para este turno |
| temperature | number | Temperatura de amostragem para este turno |
| disableTools | boolean | Desativa chamadas de ferramenta/conector para este turno |
| maxToolIterations | number | Limita as iterações do loop de chamadas de ferramenta |
| responseFormat | object | Saída estruturada: {type:"json_object"} ou {type:"json_schema", json_schema:{...}} — restringe a resposta final (somente modelos compatíveis com OpenAI) |
| stream | boolean | Streaming de tokens via Server-Sent Events: eventos de token conforme a resposta é gerada e, em seguida, um evento de resultado final com o corpo JSON padrão (somente bot único) |
Cabeçalho opcional Idempotency-Key: <uuid> — reenviar a mesma chave para a mesma chave de API reproduz a resposta armazenada (sem cobrança dupla / sem reexecutar ferramentas).
Formato da Resposta
{
"response": "I've logged error E42. Let me pull up the matching fix steps.",
"conversationId": "sess_001",
"runId": "run_8f3a21c9",
"model": "openai/gpt-4.1-mini",
"latencyMs": 1840,
"tokens": { "prompt": 1203, "completion": 88, "total": 1291 },
"guardrails": {
"inputBlocked": false,
"outputBlocked": false,
"outputRewritten": false,
"blockedBy": null,
"escalated": false,
"escalatedBy": null
},
"toolCalls": [],
"augmentation": { "rulesApplied": 0, "skillsMatched": 1, "episodicRecallCount": 0, "userModelApplied": false },
"sessionEnd": null,
"kb": null,
"pendingApproval": null
}
Campos Principais da Resposta
| Campo | Descrição |
|---|---|
| response | O texto da resposta do assistente para mostrar ao usuário |
| runId | ID exclusivo deste turno — encontre-o no Dashboard → Rastreamentos |
| conversationId | Ecoa o sessionId da solicitação |
| model | O modelo que realmente atendeu ao turno |
| latencyMs | Latência do turno no lado do servidor (ms) |
| tokens | Contagens de tokens { prompt, completion, total } |
| guardrails | { inputBlocked, outputBlocked, outputRewritten, blockedBy, escalated, escalatedBy } — inputBlocked = a mensagem foi recusada antes de o modelo ser executado; outputBlocked = a resposta foi bloqueada após ser gerada |
| toolCalls | Ferramentas invocadas neste turno (nome, disposição, latência, custo) |
| sessionEnd | Definido quando o bot encerrou a sessão ({ reason, summary? }) |
| kb | Telemetria de fundamentação de KB, incluindo citações (quando a recuperação foi executada) |
| pendingApproval | Presente quando uma chamada de ferramenta aguarda aprovação do operador |
Fluxos
Fluxos são um grafo de conversa guiado/estrito opcional anexado a um bot (bot.flowId) ou a um grupo de agentes (gerenciado pelo dashboard/MCP) que molda seu comportamento em runtime — eles não fazem parte da solicitação ou resposta /api/v1/bot-run. Um fluxo é um conjunto de etapas: o mecanismo mantém um ponteiro por sessão para a etapa atual, injeta o objetivo dessa etapa no prompt do sistema, limita suas ferramentas e avança quando uma transição é acionada.
Uma etapa carrega
goal Injetado no prompt do sistema como a instrução desta etapa
collect Informações a solicitar antes de prosseguir — o fluxo mantém o que o bot não pode salvar
allowed_tools Estrito: as únicas ferramentas oferecidas. Guiado: nomeado para o bot como orientação
transitions Arestas para a próxima etapa, avaliadas a cada turno
Tipos de transição
always Aciona incondicionalmente
data_complete Todos os campos de coleta da etapa são reunidos
intent A intenção classificada corresponde
condition Uma expressão sobre os campos (nula até ser fornecida), detalhes rastreados como estado.<key>, e turn_count / step_turns é verdadeira
tool_result Uma ferramenta nomeada foi executada com sucesso neste turno
Como a intenção é classificada: quando uma etapa tem transições intent, TypeSafe Jev escolhe uma das intenções dessa etapa. Uma transição é tomada somente quando o Jev tem pelo menos 50% de certeza; caso contrário, o fluxo permanece na etapa. Se o Jev não puder responder, o classificador de LLM anterior no modelo do bot decide.
Estágios do fluxo de trabalho do bot (bot.workflowId, separados dos fluxos): quando o fluxo de trabalho define dois ou mais estágios, o mecanismo escolhe o estágio atual a cada turno a partir dos IDs de estágio do próprio fluxo de trabalho e pontua o sentimento do usuário de -1 (furioso) a 1 (encantado) na mesma solicitação do Jev. Condições sentiment < … nas regras de escalonamento do fluxo de trabalho agora comparam com essa pontuação; antes, o mecanismo usava uma constante 0.
Tratamento de Erros
400
Solicitação Inválida
JSON malformado, mensagem ausente, botId/groupId ausente ou formato de campo incorreto.
401
Erro de Autenticação
Chave de API ausente ou inválida.
403
Proibido
A chave não tem o escopo, está vinculada a um bot diferente ou a organização está suspensa.
404
Não Encontrado
Bot, grupo ou recurso não encontrado.
429
Limite de Taxa
Limite de taxa por chave excedido — consulte o cabeçalho Retry-After.
502 / 503
Mecanismo Indisponível
Mecanismo de runtime inacessível, não configurado ou temporariamente desativado.
Engine-side failures (e.g. a missing BYOK provider key) pass through the engine's status code with its own code / error.
// Error response format
{
"error": "One of \`botId\` or \`groupId\` is required.",
"code": "invalid_request"
}
Exemplo de múltiplas interações
Mantenha um sessionId estável e passe a transcrição em andamento em conversationHistory para que o bot tenha contexto.
Interação 1 - Usuário relata problema
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
-d '{"botId":"bot_abc123","sessionId":"conv_001","message":"My subscription renewal failed."}'
Interação 2 - Usuário fornece o número do pedido (inclua as interações anteriores)
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
-d '{"botId":"bot_abc123","sessionId":"conv_001","message":"My order is ORD-98765-XYZ","conversationHistory":[{"role":"user","content":"My subscription renewal failed."},{"role":"assistant","content":"I can help — what is your order number?"}]}'
Interação 3 - Usuário quer escalonamento
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
-d '{"botId":"bot_abc123","sessionId":"conv_001","message":"I want to talk to a real person."}'
Webhooks
/api/v1/bot-run é síncrono — o resultado da interação é retornado na resposta. Para notificações assíncronas (escalonamentos, mudanças de estágio, falhas de verificação, resultados de ferramentas), registre um Event Connector (Dashboard → Connectors, ou pela superfície MCP). A Rylvo envia via POST cada evento assinado para o seu endpoint com o método de autenticação e o segredo de assinatura HMAC que você configura no conector. Os tipos de eventos assináveis estão listados em Connectors.
Limites de taxa
POST /api/v1/bot-run tem limite de taxa por chave de API — 60 requisições/minuto por padrão, configurável por chave (Dashboard → API Keys). O chat do bot iniciado pelo dashboard usa sua própria chave BYOK e NÃO tem limite de taxa imposto pela Rylvo; os recursos de IA da plataforma (Agent Evolution, Self-Improving Prompts, Red Team) também usam sua própria chave de LLM e são gratuitos — veja pricing.
| Plano | Mensal | Respostas do bot |
|---|---|---|
| Free | $0 | Uso justo |
| Lite | $40 | Uso justo |
| Pro | $100 | Uso justo · guia ≈ 100K/mês |
| Enterprise | Personalizado | Definido no seu contrato |
As respostas do bot são de uso justo: nada mede ou cobra por elas em cada plano, e os valores acima são guias, não limites.
Cabeçalhos de limite de taxa em cada resposta: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset e Retry-After em 429.
Cobrança e uso
O modelo de cobrança da Rylvo é simples: um plano de assinatura mensal cobre a capacidade da plataforma (bots, prompts, guardrails, fontes de KB, conectores, observabilidade), e todo recurso de IA roda na sua própria chave de LLM (BYOK) gratuitamente.
Sua chave de LLM (BYOK)
Todo recurso de IA — gratuito
Chat do bot, Workspace Architect, Agent Evolution, Self-Improving Prompts, Edge Case Engine, Red Team, broadcasts — tudo roda na sua própria chave de provedor sem margem. Sem créditos de IA, sem margem. A indexação da base de conhecimento está incluída até o limite do seu plano. Durante o teste gratuito de 14 dias do Pro, até $2 de uso de IA estão incluídos; depois disso, tudo usa a sua chave.
Carteira pré-paga (opcional)
Excedente de armazenamento de conversas
Uma carteira pré-paga em USD cobre apenas o excedente de armazenamento de conversas além do pool incluído no seu plano e complementos de retenção financiados pela carteira. A Dodo cobra as assinaturas do plano separadamente. Recarregue a partir de $5 em Dashboard → Billing. Os recursos de IA nunca usam essa carteira.
Planos de assinatura
| Plano | Preço | Limites principais | Observações |
|---|---|---|---|
| Free | $0 | 1 bot · retenção de rastreamento de 7 dias | Sua própria chave de IA, sem margem; respostas do bot são uso justo |
| Lite | $40 | 3 bots · retenção de rastreamento de 14 dias | Kit para criadores individuais; sem suíte avançada de IA ou Broadcasts |
| Pro | $100 | 25 bots · retenção de rastreamento de 90 dias | Suíte avançada de IA + Broadcasts |
| Enterprise | Personalizado | Negociado | DPA personalizado, revisão de segurança, contato nomeado (próximo dia útil, não é um SLA) |
Suíte avançada de IA (Pro+): Agent Evolution, Self-Improving Prompts, Edge Case Engine, Red Team, Mission Control, Audit Log Export, Custom Policy Blocks. Broadcasts (Pro+): campanhas de saída multicanal. O Lite mantém Advanced Analytics, BYODB, Test Suites, MCP Hub, Webhooks e Build Intelligence. Assentos (Pro+): o Pro inclui o seu assento; cada colega adicional custa $40/assento/mês ($32 na cobrança anual), até 100 assentos no total.
Teste, reembolsos e impostos
- Teste. Todo novo workspace começa no Pro por 14 dias com até $2 de uso de IA (concedido após a verificação do seu e-mail), sem cartão. Quando termina, o workspace passa para o Free (1 agente) a menos que você faça upgrade, e o uso de IA do teste termina junto, então adicione sua própria chave de provedor para seus agentes continuarem respondendo. Com mais de um agente, você tem 7 dias para escolher qual manter (ou fazer upgrade); depois disso, os extras são pausados, nunca excluídos, e quando você faz upgrade eles voltam a funcionar se todos couberem no limite de agentes do seu novo plano (caso contrário, você escolhe quais rodam). Agentes de demonstração que você não tornou seus são removidos no fim do teste; um que você alterou, implantou ou usou com pessoas reais é seu para manter.
- Reembolsos. Envie um e-mail para contact@rylvo.com dentro de 14 dias do seu primeiro pagamento em um plano pago (mensal ou anual) e reembolsamos integralmente via Dodo Payments, uma vez por cliente, a menos que a conta tenha sido suspensa por violar os Termos. Renovações, assentos, outros complementos e recargas de carteira comprados depois não são reembolsáveis, exceto quando exigido por lei ou sob os termos do comprador da Dodo Payments. Terms: Billing & Payment.
- Moeda e impostos. Os preços estão em USD. A Dodo Payments é o comerciante de registro e o GST da Índia é adicionado no checkout.
- Intervalo de cobrança. Mensal ou anual no Lite e Pro (anual é cerca de 20% menor). O Starter é apenas mensal.
Custo de tokens (BYOK — informativo)
As interações do bot rodam na sua própria chave de provedor, então a Rylvo não cobra por token — você paga diretamente ao seu provedor de LLM. Cada interação ainda registra seu custo de tokens no rastreamento para observabilidade e acompanhamento de orçamento por bot:
trace.cost_usd = (input_tokens × model.price_per_input_token)
+ (output_tokens × model.price_per_output_token)
Cabeçalhos de resposta em /api/v1/bot-run
| Cabeçalho | Significado |
|---|---|
| X-RateLimit-Limit | Capacidade de requisições por minuto da chave |
| X-RateLimit-Remaining | Requisições restantes na janela atual de limite de taxa |
| X-RateLimit-Reset | Segundos Unix quando a janela reinicia |
| Retry-After | Segundos para esperar antes de tentar novamente (em 429) |
| Idempotent-Replay | true quando uma resposta idempotente armazenada é reproduzida |
Estado da assinatura Somente no dashboard
A assinatura de cobrança é um documento singleton no Firestore. As transições de estado são conduzidas por webhooks do provedor mais um cron de ciclo horário. Apenas o status downgraded desativa os recursos pagos. IDs de planos legados (starter é um alias antigo do Pro, além de growth e scale) são migrados no momento da leitura; o plano Starter atual tem o ID solo.
Portões de plano
requireFeature— recurso bloqueado ou rebaixadorequireQuota— uso ≥ limite do planorequireProviderKey— recurso de IA precisa da sua própria chave de LLM (BYOK, gratuito)requireStorageEventsBudget— pool de armazenamento esgotado- Retorna
PlanAccessErrorcomupgradeTarget
Arquitetura de outbox durável
- As rotas de API publicam em um
billingOutboxdurável antes do Pub/Sub - A Cloud Function
billingOutboxWorkeré o único gravador de conta - Transações atômicas com idempotência + clamp negativo
- O
billingReconciliationdiário executa verificações de integridade do razão - Design baseado em portas: todo código de cobrança depende de interfaces abstratas
Limite de orçamento por bot
Cada bot pode ter um limite de gasto mensal. O portão soma o custo observado (BYOK) do bot a partir do armazenamento canônico de observabilidade via sum_cost_by_bot e pausa o bot quando o limite é excedido. Defina limites nas configurações do bot.
Recarga e razão Somente no dashboard
A carteira pré-paga (excedente de armazenamento de conversas + complementos de retenção) recarrega em qualquer valor de $5 a $10.000 em Dashboard → Billing. Cada débito e crédito é registrado em um razão de transações imutável que você pode revisar e exportar na página de Billing (detalhamento por bot, detalhamento por modelo, intervalo de datas, CSV).
As interações do bot são BYOK — /api/v1/bot-run não usa a carteira pré-paga nem retorna 402 por saldo. A carteira cobre apenas o excedente de armazenamento de conversas e complementos de retenção financiados pela carteira; a Dodo cobra o plano separadamente.
Rastreamentos e análises
Cada decisão é rastreada em um único armazenamento canônico — Postgres rylvo-obs (observability_traces → observations → scores). A gravação dupla legada do Firestore chatTraces foi descontinuada. Você pode reproduzir qualquer interação passada, listar cada execução em uma sessão e obter análises agregadas por empresa no dashboard. Os endpoints do mecanismo abaixo sustentam essas visualizações — eles são internos (dashboard / MCP), não fazem parte da superfície REST pública.
Endpoints internos (alimentam o dashboard)
| Método | Caminho | Descrição |
|---|---|---|
| GET | /v1/traces/{trace_id}/replay | Payload completo de reprodução para um rastreamento (pilha de prompts, guardrails, chamadas de ferramentas, tempos por estágio) |
| GET | /v1/sessions/{session_id}/traces?limit=50 | Lista cada execução em uma sessão, mais recentes primeiro |
| GET | /v1/analytics/companies/{company_id}/overview?limit=500&top_n=10 | Taxa de escalonamento, latência média e agregações de tokens/custos na janela |
| GET | /v1/analytics/companies/{company_id}/runs?limit=100 | Execuções individuais recentes de uma empresa |
Caminhos de gravação
- Mecanismo:
make_observability_ingest_hook(canais ao vivo) - Playground / Architect: adaptadores →
POST /v1/observability/ingest - Contexto rico do operador em
metadata.turn_context - Observações hierárquicas: spans, gerações, ferramentas, guardrails, retriever, agente
Caminhos de leitura
- Rastreamentos do dashboard: projetores com suporte canônico
- Análises:
analytics-rowsagregações Postgres - Cobrança:
sum_cost_by_bot(limite por bot) - Público / GDPR: linhas canônicas de clientes
Decisões tipadas (TypeSafe Jev)
Algumas decisões dentro de uma interação apenas escolhem um rótulo, então o mecanismo as faz como perguntas tipadas ao TypeSafe Jev ("System One" da TypeSafe AI) — um modelo somente de decisões que escolhe uma de N opções, responde sim/não ou coloca texto em uma escala ordenada, com probabilidade calibrada, e nunca escreve texto. Cada site mantém sua implementação anterior como fallback automático quando o Jev não consegue responder, e um disjuntor torna esse fallback imediato durante uma interrupção. O Jev roda na chave TypeSafe da própria Rylvo, não na sua chave de provedor BYOK; o fallback usa sua chave como antes.
- Guardrails: regras de avaliação personalizadas no mesmo texto, em uma única requisição
- Flows: transições de intenção; estágio do fluxo de trabalho do bot + sentimento
- Agent Groups: despacho de roteador somente por intenção; fan-out
vote - Knowledge Base: classificação de relevância Self-RAG
- Mission Control: o sinal de risco da conversa
Cada requisição do Jev é uma observação generation no rastreamento — nomeada como jev-guardrail-check, jev-workflow-stage, jev-kb-relevance ou jev-flow-intent — com modelo typesafe/jev-latest, tokens, custo, latência e cada pergunta com sua resposta e probabilidade. É precificada como qualquer outra geração e conta para o total do rastreamento. O texto da pergunta pode citar seu cliente, então é armazenado apenas quando o bot captura entradas. Quando o Jev não respondeu, o passo registra o erro e que a implementação anterior decidiu. O sinal de risco não é um passo do rastreamento; ele aparece com os sinais de risco da conversa no Mission Control. As organizações podem desativar o Jev nas Configurações, e cada decisão então usa sua implementação anterior.
Armadilha de datetime: as colunas de observabilidade started_at são TIMESTAMP WITHOUT TIME ZONE. Sempre use UTC ingênuo no limite do repositório; datetimes com fuso horário são rejeitados pelo asyncpg.
Exemplo de reprodução
curl https://rylvo.com/api/v1/traces/tr_def456/replay \
-H "X-API-Key: YOUR_API_KEY"
Analytics Somente no dashboard
Gráficos em cada resposta que seus bots enviam, lidos do armazenamento canônico de observabilidade (Postgres) — as mesmas respostas que a página de Rastreamentos lista. Cada parte tem sua própria página em Dashboard → Analytics: salas (cada sala, suas configurações e cada widget), a biblioteca de widgets, modelos, alertas e links compartilhados.
Salas
Uma grade nomeada de widgets com seu próprio intervalo e bot.
- Última hora, 24 horas, 7, 30 ou 90 dias, todo o período ou dias personalizados no fuso horário do workspace
- O intervalo e o bot estão na URL, então um link abre a mesma visualização
- Clique em um ponto, barra ou fatia para abrir essas respostas em Rastreamentos
- Teste e Produção têm suas próprias salas; lançamentos não as carregam
Widgets
O que contar, a medida, como dividir e o gráfico.
- Contar respostas, chamadas de ferramentas ou respostas pagas
- Respostas, pessoas alcançadas, conversas, custo, tokens, tempo de resposta, taxa de sucesso / falha / aviso / bloqueio / erro
- Ao longo do tempo, ou por bot, modelo, canal, resultado ou usuário final — como número, linha, colunas, barras, rosca, distribuição ou tabela
- Um widget pode restringir o intervalo ou o bot da sala, nunca ampliá-lo; blocos de números comparam com o período anterior
Biblioteca e modelos
- Uma biblioteca de widgets para Teste e Produção
- Adicionar um widget da biblioteca a uma sala cria uma cópia — alterar a biblioteca não altera as salas
- 10 modelos — Visão geral, Agora, Qualidade, Velocidade, Custo, Canais, Clientes, Bots comparados, Ferramentas, Modelos — visualizados com seus números ao vivo
- Um espaço de trabalho vazio começa com uma sala de Visão geral dos últimos 7 dias
Alertas
- Taxa de erro, taxa de aviso, tempo de resposta (p95), custo por resposta ou gasto diário igual ou acima de um limite
- Um bot ou todos os bots; Produção, Teste ou ambos
- Verificado a cada 5 minutos aproximadamente; quando um dispara, cada membro recebe uma notificação no aplicativo e, em seguida, aguarda o período de resfriamento
- O formulário mostra qual é o número no momento
Compartilhamento, eventos e exportação
- Um link de compartilhamento é um instantâneo — números como estavam, nunca o texto da resposta; usuários finais aparecem como “Cliente 1, 2…”
- Os links expiram (padrão do espaço de trabalho, até o máximo) e podem ser desativados
- Eventos marcam um lançamento ou um incidente nos gráficos de tempo de uma sala
- Exporte os números dos widgets de uma sala, ou as respostas por trás deles, como CSV ou JSON
Quanto é lido
- Até 20.000 respostas mais recentes no intervalo, 2.000 por página
- Quando um intervalo contém mais, a sala informa quais dias seus números cobrem
- Respostas ainda em execução e turnos do Workspace Architect são deixados de fora
Funções e plano
O Advanced Analytics está disponível a partir do Lite; espaços de trabalho Free veem um aviso de upgrade. Visualizadores veem todas as salas e podem exportar; operadores criam salas, editam widgets, salvam na biblioteca e adicionam eventos; administradores excluem salas, gerenciam alertas, criam links de compartilhamento e excluem widgets da biblioteca.
Referência de AnalyticsSomente painel
As formas e os endpoints internos por trás do Analytics. As salas são lidas do Firestore em tempo real e gravadas apenas por meio do mecanismo, que verifica a organização, o plano e a função e grava uma entrada de auditoria. Nenhum desses endpoints é REST público.
Endpoints internos (mecanismo)
- GET /v1/analytics-rooms/{company_id} — lista de salas
- GET /v1/analytics-rooms/{company_id}/{room_id} — uma sala (404 se ausente)
- POST /v1/analytics-rooms/{company_id} — criar (operadores+; 201, { room_id, ok })
- PUT /v1/analytics-rooms/{company_id}/{room_id} — alterar nome, filtros ou gráficos (operadores+)
- DELETE /v1/analytics-rooms/{company_id}/{room_id} — excluir (administradores; idempotente)
- GET /v1/observability/orgs/{org_id}/analytics-rows — respostas para gráficos, mais recentes primeiro, ≤ 2.000 por chamada
- POST /v1/observability/orgs/{org_id}/alerts — criar ou atualizar quando um id é enviado (administradores)
- POST /v1/observability/orgs/{org_id}/alerts/check — o número de um alerta agora (qualquer membro)
Alterações em salas são auditadas (analytics_room_created / updated / deleted), assim como links de compartilhamento (analytics.share_created / analytics.share_revoked).
Alertas
metric: error_rate, warning_rate, p95_latency_ms, avg_cost_usd, daily_spendenvironment: production, test, ou null para ambos;botIdnull = todos os bots- As taxas são armazenadas como frações (0,05 = 5%); o formulário trabalha em percentual
- Dispara igual ou acima do limite com pelo menos
minTracesrespostas e, em seguida, aguardacooldownMinutes
Funções
analytics.view— visualizadoranalytics.edit,analytics.annotate— operadoranalytics.manage,analytics.share— administrador- Widgets da biblioteca: operadores gravam, administradores excluem; eventos e links de compartilhamento são somente servidor
Forma do Firestore
{envRoot}/analyticsRooms/{roomId} (Test and Production each have their own)
|- name (1-200), createdBy, createdAt, updatedAt
|- filters: { botId, env, dateRange } (the room's own range and bot)
+- charts: [{ id, type, position, title?, width?, height?, color?,
customWidget?: WidgetConfig }]
WidgetConfig:
view: traces (replies) | tool_calls | cost (paid replies)
metric: count | total_cost | p95_latency | error_rate | ... (20)
breakdown: none | time | bot | model | status | user | channel | ...
chartType: big_number | line | bar_v | bar_h | pie | histogram | pivot
filters: [{ id, column, op, value }], dateRange (narrows only), topN? (10)
{orgRoot}/analyticsWidgets/{widgetId} library (Test + Production)
{orgRoot}/analyticsAnnotations/{id} events (server-written)
analyticsShares/{token} share links + snapshot (server-only)
SDKs e Bibliotecas
Python
import requests
resp = requests.post(
"https://rylvo.com/api/v1/bot-run",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"botId": "bot_abc123def456",
"sessionId": "sess_001",
"message": "I can't access my account.",
},
)
data = resp.json()
print(data["response"])
print(f"run {data['runId']} · {data['tokens']['total']} tokens")
JavaScript / Node.js
const res = await fetch("https://rylvo.com/api/v1/bot-run", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
},
body: JSON.stringify({
botId: "bot_abc123def456",
sessionId: "sess_001",
message: "I can't access my account.",
}),
});
const data = await res.json();
console.log(data.response);
console.log(data.runId, data.tokens.total, "tokens");
PromptsSomente painel
Prompts são as instruções que seus agentes seguem em tempo de execução. Crie-os no painel de Prompts, atribua-os a bots e, opcionalmente, ative a otimização auto-melhorável.
Conceitos-chave
Categorias de Agentes
9 categorias: Sistema, Compositor de Resposta, Classificador de Estágio, Seletor de Ação, Classificador de Escalonamento, Resumidor de Sessão, Verificador, Recuperação, Personalizado
Espaços reservados
Use a sintaxe {{key}} para valores dinâmicos resolvidos em tempo de execução (nome da empresa, tom, idioma, etc.)
Auto-melhorável
Ative prompts auto-melhoráveis para permitir que o sistema gere, avalie e promova melhores variantes de prompt
Atribuição de Bot
Atribua prompts a bots específicos ou deixe-os compartilhados entre todos os bots
Criando um Prompt
1
Escolha uma categoria de agente
Selecione o tipo de agente que este prompt controla (ex.: Compositor de Resposta, Verificador).
2
Escreva o conteúdo do prompt
Use a sintaxe {{placeholder_key}} para valores dinâmicos. Modelos são fornecidos para cada categoria.
3
Adicione espaços reservados
Defina chaves, rótulos, valores padrão e se são obrigatórios. Use a biblioteca de modelos para os comuns.
4
Atribua a um bot (opcional)
Vincule o prompt a um bot específico ou deixe-o compartilhado. Marque solicitações com prompt_id na API.
5
Ative o auto-melhorável (opcional)
Ative a auto-otimização no painel de detalhes do prompt. Escolha uma estratégia, métrica e frequência.
Sintaxe de Espaço Reservado
Espaços reservados usam sintaxe de chaves duplas: {{key}}. Em tempo de execução, eles são resolvidos com valores da solicitação da API ou padrões.
You are a support agent for {{company_name}}.
Greet the user as {{user_name}} in a {{tone}} tone.
Respond in {{language}}. Keep replies under {{max_length}} tokens.
{{context}}
Modelos de Espaço Reservado Integrados
| Chave | Padrão | Descrição |
|---|---|---|
| {{company_name}} | Acme Corp | O nome da empresa do cliente |
| {{user_name}} | John | O nome de exibição do usuário final |
| {{product_name}} | Widget Pro | O produto em discussão |
| {{industry}} | Technology | O setor vertical do cliente |
| {{tone}} | professional | Tom da resposta (formal, casual, empático) |
| {{language}} | English | Idioma da resposta |
| {{max_length}} | 256 | Comprimento máximo da resposta em tokens |
| {{context}} | - | Contexto adicional para o prompt |
Histórico de Versões
Cada edição em um prompt cria uma nova versão. As versões são rastreadas como manual ou auto_optimized. Você pode visualizar, comparar e promover qualquer versão para ativa no painel de detalhes do prompt.
Herança de prompts
Divida um prompt definindo um parentPromptId. O filho herda o modelo base e pode adicionar suas próprias substituições, mantendo a linhagem rastreada no histórico de versões. Isso é útil para variações por bot ou por grupo de um prompt compartilhado.
Grafo de dependências
O painel de Prompts tem um grafo SVG interativo mostrando como prompts, bots e grupos de agentes se relacionam.
Layout do grafo
- Bots à esquerda → Prompts no centro → Grupos de agentes à direita
- As arestas mostram atribuições de prompt de bot via
prompt.botId - Prompts de nível de organização (botId = null) conectam-se a um nó virtual da organização
- Herança pai → filho desenhada dentro da coluna de prompts
- Prompts compartilhados por grupo conectam-se ao seu grupo de agentes
Interações
- Clique em um prompt → abre os detalhes do prompt
- Clique em um bot → abre a página do bot
- Passe o mouse sobre qualquer nó → dica de ferramenta com nome completo e metadados
- Role/pinça para ampliar, arraste para mover
- Botões de zoom/ajustar para navegação rápida
Análise de uso de prompts
O painel de detalhes do prompt mostra métricas de uso em tempo real do armazenamento canônico de rastreamento: volume de rastreamento, custo, latência e histórico de execução A/B. Use isso para decidir qual versão tem melhor desempenho antes de promovê-la.
Versionamento de RecursosSomente painel
Todo recurso que afeta o tempo de execução é versionado — não apenas prompts. Prompts, guardrails, conectores, regras de evolução e blueprints de KB rastreiam um histórico de versões imutável, além da fonte de cada edição. Você pode comparar, visualizar, promover e reverter pelo painel.
Regras e pontuação também. As regras de detecção de Edge Case (com os critérios da revisão de IA), a pontuação de teste e o portão de lançamento mantêm uma versão por salvamento — quem salvou, quando, a nota, quantas coisas mudaram — listadas em Histórico na sua página, em todos os planos. No Enterprise, Restaurar coloca uma versão anterior de volta: ela é salva como uma nova versão (o histórico mantém ambas), verificada como qualquer salvamento — um limite de plano ou uma regra que não existe mais interrompe e explica o motivo — e gravada no log de auditoria.
Como código. Cada um dos três é um documento JSON: o campo detection, scoring ou criteria do seu GET, que seu PUT recupera com base_version (um desatualizado é recusado) e um change_note opcional — para que um pipeline possa mantê-los no git. No Enterprise, Exportar baixa a versão salva como esse JSON, e Importar coloca um arquivo — uma exportação ou uma resposta de API salva — na página como alterações não salvas para verificar e salvar. Configurações que a página não possui são omitidas e nomeadas. Via MCP (Build Intelligence), os mesmos três são edge_cases.get/set_detection_rules, tests.get/set_scoring e tests.get/set_release_gate, com workspace.restore_config_version para restaurar um — salvar é para administradores e proprietários, e o histórico nomeia a pessoa (“Alex via MCP”).
Fontes de edição
human
Edição manual por um colega pelo painel
architect
Aplicado via Workspace Architect (modo de configuração / edição conversacional)
auto_generated
Produzido pelo otimizador Self-Improving ou gerador de regras de Agent Evolution
fix_proposal
Aceito de uma proposta de correção do Edge Case Engine
system
Migração interna ou seed padrão
red_team
Criado em resposta a uma descoberta de red-team
O que é versionado
Bots
Prompts
Guardrails
Conectores
Regras de Evolução
Blueprints de KB
O que você pode fazer pelo painel
- Ver o histórico completo de edições de qualquer recurso (quem, o quê, quando, por quê)
- Comparar duas versões lado a lado
- Visualizar uma versão antes de promovê-la para ativa
- Promover qualquer versão passada de volta para ativa em um clique (reversão)
- Filtrar o histórico por fonte — manual, arquiteto, gerado automaticamente, etc.
Cada decisão em tempo de execução registra qual versão estava ativa quando foi executada, para que você possa correlacionar mudanças de desempenho com edições específicas — não apenas qual recurso foi usado, mas qual versão dele.
Prompts Auto-MelhoráveisSomente painel
O Rylvo implementa otimização automática de prompts com base em pesquisa. Quando ativado, o sistema gera, avalia e seleciona continuamente melhores variantes de prompt usando dados reais de desempenho.
Como Funciona
1. Coletar
O sistema reúne métricas de desempenho de solicitações reais de API que usam este prompt — taxa de sucesso, taxa de aprovação na verificação, sinais de satisfação do usuário e latência.
2. Gerar
Um LLM otimizador analisa o histórico de prompts pontuados e propõe N variantes melhoradas. Cada variante preserva todos os espaços reservados e a intenção central, mas tenta uma estratégia de melhoria diferente.
3. Avaliar
Cada variante é pontuada em relação à sua métrica escolhida. A pontuação usa análise estrutural, qualidade das restrições e padrões históricos de desempenho.
4. Selecionar
A variante com melhor desempenho é identificada. Ela deve superar o prompt atual em pelo menos o limite de melhoria (padrão 2%) para se qualificar.
5. Promover ou Sugerir
Se a auto-promoção estiver ativada, o vencedor se torna automaticamente o prompt ativo. Caso contrário, ele aparece no histórico de versões para revisão manual.
Estratégias de Otimização
Quatro estratégias com base em pesquisa estão disponíveis. Cada uma usa uma abordagem diferente para melhoria de prompts.
OPRO
Yang et al., 2023 - Google DeepMind
Otimização por PROmpting. Alimenta histórico pontuado de (prompt, desempenho) a um LLM que propõe variantes melhoradas. Insight central: LLMs podem atuar como otimizadores quando recebem exemplos com pontuações.
Melhor quando você tem histórico de versões com pontuações diversas.
APE
Zhou et al., 2023 - Universidade de Toronto
Engenheiro Automático de Prompts. Gera candidatos diversos usando múltiplas estratégias de melhoria (instruções explícitas, exemplos, reestruturação, guardrails, simplificação), avalia cada um e seleciona o melhor.
Melhor para prompts novos com pouco histórico.
DSPy Bootstrap
Khattab et al., 2023 - Stanford Compila os padrões de melhor desempenho do histórico em demonstrações few-shot otimizadas. Extrai o que funciona e incorpora diretamente no prompt como exemplos.
Melhor uso quando existem versões de alta pontuação para aprender.
PromptBreeder
Fernando et al., 2023 - Google DeepMind
Evolução autorreferencial. Aplica prompts de mutação (torne conciso, adicione restrições, reestruture, adicione raciocínio, adicione role-playing) para evoluir o prompt da tarefa. As próprias mutações podem evoluir.
Melhor para exploração criativa do espaço de prompts.
Opções de Configuração
| Opção | Padrão | Descrição |
|---|---|---|
| Estratégia | OPRO | Qual algoritmo de otimização usar |
| Métrica de Avaliação | Taxa de Sucesso | success_rate | verification_pass | user_satisfaction | latency |
| Frequência de Execução | Diária | hourly | daily | weekly | manual |
| Auto-Promoção | Desativado | Promover automaticamente variantes vencedoras para ativas |
| Limiar de Melhoria | 2% | Melhoria mínima necessária para se qualificar como vencedor |
| Máx. de Variantes por Execução | 5 | Número de variantes candidatas geradas por execução de otimização |
| Tamanho Mínimo da Amostra | 50 | Solicitações mínimas de API antes da primeira execução de otimização |
Ativando a Auto-Melhoria
1
Abra o painel de detalhes do prompt
Clique em qualquer prompt na página Prompts para ver seus detalhes.
2
Expanda 'Prompts Auto-Melhoráveis'
Clique no cabeçalho do painel para expandir as configurações de otimização.
3
Ative 'Habilitar Auto-Melhoria'
Isso ativa o loop de otimização para este prompt.
4
Escolha sua estratégia
Selecione OPRO, APE, DSPy Bootstrap ou PromptBreeder dependendo das suas necessidades.
5
Defina sua métrica e frequência
Escolha o que otimizar e com que frequência executar.
6
Decida sobre a auto-promoção
Ative para implantar automaticamente variantes vencedoras, ou deixe desativado para revisão manual.
Uso da API de Prompts
Os prompts são atribuídos a um bot no painel (ou via superfície MCP), versionados e resolvidos automaticamente quando o bot é executado. /api/v1/bot-run não aceita um prompt_id ou prompt_overrides — para alterar qual prompt um bot usa, atualize sua atribuição de prompt.
Como os prompts são resolvidos em tempo de execução
1
Resolver
Os prompts atribuídos ao bot carregam suas versões ativas.
2
Substituir
Todos os valores {{placeholder}} são preenchidos a partir dos padrões do bot/organização.
3
Injetar
O texto resolvido torna-se parte do prompt do sistema para a interação.
4
Rastrear
O trace registra quais versões de prompt estavam ativas (alimenta análises + Prompts Auto-Melhoráveis).
Alterar ou fazer A/B de um prompt
- Atualize a atribuição de prompt de um bot em Dashboard → Bots (ou na página Prompts).
- Use Prompts Auto-Melhoráveis para fazer A/B de variantes e auto-promover vencedoras.
- O trace de cada interação registra a versão do prompt resolvido para análises e otimização.
Edge Case Engine Somente no painel
Detecte, classifique e corrija automaticamente modos de falha do bot
O Edge Case Engine examina os traces do seu bot e arquiva o que eles realmente registraram em 15 categorias, com os traces como evidência. Funciona em quatro estágios: Observar → Detectar → Classificar → Triagem, e um caso resolvido reabre sozinho se o problema voltar. Gerencie em Dashboard → Edge Cases. Recurso do plano Pro+.
3 mecanismos de detecção
- Varredura de traces —
POST /v1/edge-cases/{org}/scanarquiva o que cada trace registrou (vereditos de falha e lacunas de conhecimento), um caso por sinal por bot, com os traces como evidência. 10 varreduras/min por organização - Revisão por IA — opcional: um modelo que você escolhe lê as conversas reais e só pode relatar defeitos visíveis na resposta, citando o trace. Executa gratuitamente na sua própria chave de LLM (BYOK)
- Testes adversariais de Red Team — 13 estratégias integradas com entradas estáticas + geradas por LLM, executadas de forma síncrona no Cloud Run com checkpointing por resultado
12 categorias de casos de borda
- Alucinação — resposta não fundamentada em evidências da base de conhecimento
- Violação de Política — quebrou política da empresa/fluxo de trabalho
- Escalação Perdida — deveria ter escalado, mas não escalou
- Ferramenta Errada — selecionou ferramenta incorreta
- Chamada de Ferramenta Ausente — deveria ter chamado a ferramenta, mas pulou
- Estágio Errado — identificou erroneamente o estágio do fluxo de trabalho
- Memória Desatualizada — usou fatos de sessão desatualizados
- Intenção Desconhecida — intenção não coberta pelo fluxo de trabalho
- Violação de Tom — não corresponde às diretrizes da marca
- Vazamento de PII — expôs informações pessoais sensíveis
- Loop Detectado — bot preso em padrão repetitivo
- Personalizado — categoria definida pelo usuário
Ciclo de vida do status e gravidade
5 níveis de gravidade (crítico=5, alto=4, médio=3, baixo=2, informativo=1) ordenados por peso.
Fluxo de status:
open → acknowledged → fix_proposed → fix_applied → resolved
Alternativa: descartado (falso positivo) ou excluído (remoção permanente).
Correções
Sugerir correções em um caso de borda (ou em Correções) fornece as correções da Rylvo para esse tipo de problema, além de até três que a IA escreve para a conversa exata na sua chave de modelo. Cada uma é de um dos quatro tipos:
- Guardrail — adicionado em Teste com um clique (ou editado antes); um release o coloca em produção
- Prompt — texto para adicionar ao prompt do bot: copie, adicione, marque como concluído
- Conhecimento — uma resposta para adicionar a uma base de conhecimento e depois marcar como concluída
- Configuração — etapas para verificar, com um link para o local
A Rylvo nunca edita um prompt ou uma base de conhecimento por você. As correções também podem ser postadas via API (POST /v1/red-team/{org}/fix-proposals).
Ciclo de vida: a fazer → concluído / descartado
13 estratégias de Red Team
- policy_probe, hallucination_bait, tool_confusion, escalation_boundary
- injection_attempt, context_overflow, mcp_abuse, pii_extraction
- multi_turn_coercion, jailbreak_dan, function_leak, billing_bypass, kb_poisoning
Ajuste: orçamento de execução de 240s, timeout de 45s por interação, 6 concorrentes, máx. 25 testes/estratégia. Guardrails disparam como em produção; cobrança/governança ignoradas (execuções sintéticas gratuitas).
Deduplicação e RBAC
ID determinístico de SHA256(botId::categoria::título). Varreduras duplicadas incrementam occurrenceCount.
edgeCases.view— visualizador+edgeCases.manage— administrador+guardrails.view— visualizador+guardrails.manage— administrador+redTeam.view— visualizador+redTeam.run— administrador+
4 abas do painel
Edge Cases
Filtrar por status/categoria/gravidade/bot, pesquisar, criar/editar/resolver/descartar/excluir, atribuir
Red Team
Criar execuções, selecionar estratégias, configurar, executar de forma síncrona, ver resultados, criar casos de borda a partir de falhas
Guardrails
Ver/criar/editar/alternar/excluir, condições, ações, prioridades, estatísticas de disparo, histórico de versões
Propostas de Correção
Ver/criar/aplicar/rejeitar/reverter com vinculação de teste de regressão
Estrutura do Firestore
{envRoot}/edgeCases/{edgeCaseId}
|- title, description, category, severity, status
|- source: trace_mining / red_team / manual / guardrail_trigger
|- botId, botName, traceIds[], occurrenceCount
|- sampleInput, sampleOutput, expectedBehavior
|- fixProposalId, guardrailId, tags, assignedTo
+- firstSeenAt, lastSeenAt, resolvedBy, resolvedAt
{envRoot}/fixProposals/{proposalId}
|- edgeCaseId, fixType, title, description
|- impact, confidence, status
|- details: { guardrailConfig?, promptChanges?, thresholdChanges?, customSteps? }
|- regressionTestIds[]
+- appliedBy, appliedAt, createdBy, createdAt
{envRoot}/redTeamRuns/{runId}
|- name, botId, strategies[], status
|- config: { testsPerStrategy, maxConcurrent, timeoutMs, ... }
|- results: { totalTests, passedTests, failedTests, edgeCasesFound }
+- edgeCaseIds[], startedAt, completedAt
{envRoot}/redTeamRuns/{runId}/results/{resultId}
|- strategy, testInput, botResponse, passed
|- failureCategory, failureReason, severity, edgeCaseId
|- guardrailResults[], toolCalls[], traceId, latencyMs
+- model, tokens, createdAt
Guardrails Somente no painel
Regras de segurança programáveis que são executadas em cada resposta do bot
Guardrails são regras de tempo de execução que verificam entradas/saídas do bot e agem quando as condições são atendidas. Podem ser criados manualmente ou sugeridos automaticamente pelo Edge Case Engine quando detecta padrões de falha.
Tipos de Guardrails
- Filtro de Entrada - Valida a entrada do usuário antes do processamento
- Filtro de Saída - Valida a resposta do bot antes da entrega
- Verificação de Fatos - Verifica afirmações contra a base de conhecimento
- Verificação de Política - Garante conformidade com políticas da empresa
- Detecção de PII - Detecta e redige dados sensíveis
- Verificação de Tom - Valida se o tom corresponde à marca
- Quebra de Loop - Interrompe padrões de conversa repetitivos
- Substituição de Escalação - Força escalação em condições específicas
- Portão de Ferramentas - Controla acesso a ferramentas em contextos específicos
Ações
- Bloquear - Impede a resposta, retorna mensagem substituta
- Avisar - Sinaliza para revisão, mas permite a resposta
- Reescrever - Modifica automaticamente a resposta para conformidade
- Escalar - Aciona transferência humana imediatamente
- Registrar - Grava para monitoramento, nenhuma ação tomada
Cada guardrail tem condições (campo + operador + valor) e uma mensagem substituta exibida quando acionado.
Condições e avaliação
Uma condição de guardrail é construída a partir de um campo de trace/tempo de execução, um operador e um valor. Exemplos:verification.status == fail,output.pii_detected == true, ou loop.count > 3. Guardrails são avaliados em ordem de prioridade; ações de bloqueio e escalação interrompem o restante.
Avaliação personalizada (custom_eval) condições aceitam uma regra em linguagem natural. Cada regra personalizada que verifica o mesmo texto é julgada em uma única solicitação TypeSafe Jev em vez de uma chamada de LLM por regra, e o motivo carrega a probabilidade, ex.: Violates "Never promise a refund" (p=0.94). Se o Jev não puder responder, o juiz LLM executa na sua chave; a política de falha fechada permanece inalterada — se nenhum juiz puder responder, a regra conta como violada.
Ciclo de vida e auditoria
Versionado
Cada edição é uma nova versão marcada como manual, fix_proposal, red_team, system ou auto_generated
Controlado por experimento
Alterações arriscadas podem ser implantadas atrás de um flag antes da promoção completa
Auditoria de trace
Cada decisão de guardrail é registrada nas observações do trace
Auditoria de Guardrails
Tarefa de automação agendada revisa a eficácia e sugere ajustes
Testes de Red Team Somente no painel
Descubra vulnerabilidades proativamente com testes adversariais
Execuções de Red Team geram entradas adversariais contra o seu bot para encontrar falhas antes que os usuários o façam. Selecione um bot, escolha estratégias de ataque, e o mecanismo gera casos de teste automaticamente. Os resultados são convertidos em casos de borda com níveis de gravidade.
13 estratégias de ataque integradas
- Sonda de Política - Testa condições de limite de política com entradas de caso de borda
- Isca de Alucinação - Perguntas sem resposta na base de conhecimento para testar fundamentação
- Confusão de Ferramenta / Abuso de MCP - Entradas que acionam seleção de ferramenta errada ou insegura
- Limite de Escalação - Testa o limite dos limiares de escalação
- Tentativa de Injeção / Jailbreak (DAN) - Injeção de prompt e tentativas de jailbreak
- Sobrecarga de Contexto - Conversas longas que estressam limites de memória
- Extração de PII / Vazamento de Função - Tentativas de expor dados privados ou internos do sistema
- Coerção Multi-Interação, Bypass de Cobrança, Envenenamento de Base de Conhecimento
Automação e Relatórios Somente no painel
Agende varreduras, conecte canais e gere relatórios automatizados
A página Automação em /dashboard/automation permite configurar trabalhos recorrentes, canais de notificação e relatórios analíticos automatizados. Tudo é executado no cronograma escolhido — nenhuma intervenção manual necessária após a configuração. Cada parte tem sua própria página: Visão Geral, Tarefas (cada uma com suas execuções e configurações), Relatórios (cada um com seu histórico e configurações), Relatórios gerados e Canais. Você edita automações em Teste; a cópia publicada executa e envia em Produção, enquanto execuções de Teste são salvas em cada página de tarefa e nunca enviadas.
10 modelos de tarefas agendadas
Trabalhos Cron que executam automaticamente via Cloud Function (a cada 5 min):
- trace_scan — varredura automática de traces para casos de borda
- red_team_run — testes adversariais periódicos
- guardrail_audit — revisão da eficácia dos guardrails
- complaint_watch — monitoramento de conversas com risco de reclamação
- dev_review — revisão de execuções falhas e padrões
- conversation_quality — amostragem de conversas para revisão de qualidade
- cost_usage_watch — revisão de gastos e custos de tokens registrados
- kb_gap_analysis — encontrar lacunas de conhecimento nos resultados de traces
- connector_health — auditoria de saúde de conectores/MCP
- test_suite_run — executar uma suíte de testes quando a integração do mecanismo estiver configurada
9 cadências: de hora em hora a mensal. Configuração de cronograma rica (intervalo/semanal/mensal com fuso horário IANA). Máx. 25 tarefas/invocação, 3 concorrentes/organização, timeout de 90s. Trabalhadores selecionados podem adicionar análise BYOK opcional; relatórios são configurados separadamente.
5 canais de notificação
Onde alertas e relatórios são enviados. Entrega via outbox durável com retry de backoff exponencial:
- Slack — integração via webhook
- Email — direto para caixas de entrada da equipe
- Discord — integração via webhook
- Microsoft Teams — integração via webhook
- Webhook Personalizado — qualquer endpoint HTTPS
Eventos: edge_case.created, red_team.completed, report.generated, etc. Escopo: global ou vinculado a bots específicos.
13 seções de relatório
- executive_summary, edge_cases_overview, edge_cases_by_category/severity
- guardrail_performance, red_team_results, fix_proposals_summary
- improvements_timeline, bot_comparison, complaints_and_escalations
- developer_followups, automation_coverage, recommendations (AI)
13 fontes de dados, 5 formatos de saída funcionais (html_email, slack_blocks, teams_card, discord_embed, markdown). 5 filtros de destinatários (all_members, admins_only, owners_only, operators_only, custom). Formatação LLM opcional com modelo personalizado, prompt do sistema, temperatura, máx. de tokens. A opção reservada de PDF atualmente não gera um arquivo PDF.
Limites de RBAC e planos
automation.view— viewer+automation.generate_report— operator+automation.manage_tasks— admin+automation.manage_channels— admin+automation.manage_reports— admin+
Free: 0ch, 0tasks, 0configs, 0reports/mo / Starter: 2ch, 0tasks, 0configs, 0reports/mo / Lite: 10ch, 10tasks, 2configs, 25reports/mo / Pro: 25ch, 25tasks, 5configs, 100reports/mo / Enterprise: ilimitado.
Estrutura do Firestore
{envRoot}/scheduledTasks/{taskId}
|- name, type, cadence, enabled, botId
|- config: { traceLimit?, redTeamStrategies?, aiConfig?, scheduleConfig? }
|- notificationChannelIds[], lastRunAt, lastRunStatus, nextRunAt
+- runCount, failCount
{envRoot}/notificationChannels/{channelId}
|- name, type, enabled, config, events[], botIds[], scope
+- lastUsedAt, lastStatus
{envRoot}/reportConfigs/{configId}
|- name, cadence, sections[], dataSources[], filters
|- recipientFilter, customRecipientEmails[], notificationChannelIds[]
|- aiConfig?, outputFormats[], scheduleConfig?
+- lastGeneratedAt, nextGenerateAt
{envRoot}/reports/{reportId}
|- configId, status, sections[], data, distributedTo[]
|- llmFormattedContent?, pdfUrl?, tokenUsage?
+- periodStart, periodEnd, generationDurationMs
{envRoot}/scheduledTaskRuns/{runId}
|- taskId, taskType, status, summary, details
+- startedAt, completedAt
Painel do Agent Evolution (somente dashboard)
Sistema de ciclo fechado que aprende com o tráfego real e reescreve o agente com segurança
Enquanto o Edge Case Engine captura falhas individuais, o Agent Evolution analisa padrões entre execuções e atualiza o próprio agente. Ele executa um loop de seis fases — observar, detectar, inferir, gerar, injetar, verificar — e grava novas regras, variantes de prompt ou ajustes de guardrail em recursos versionados. Cada alteração é reversível.
Fases
- Observar — amostrar traces recentes do bot
- Detectar — agrupar falhas e quase-erros
- Inferir — LLM revisor nomeia o padrão e a causa raiz
- Gerar — criar rascunho de regra, edição de prompt ou guardrail
- Injetar — anexar ao bot atrás de uma flag de experimento
- Verificar — medir o efeito; promover, manter ou reverter automaticamente
O que é gravado
- Regras de evolução (injetadas condicionalmente no prompt do sistema)
- Atualizações de versão de prompt (marcadas como
auto_generated) - Ajustes de guardrail (limiar, condição, texto de fallback)
- Insights do revisor (explicações narrativas para a equipe)
- Pontuações de eficácia por regra (controlam a promoção automática)
Abas do painel
Visão geral
Pontuação de saúde do bot, melhorias recentes, experimentos ativos e resumo de execução
Falhas
Traces com falha agrupados por causa raiz; promover para Edge Cases
Livro de regras
Regras ativas e pendentes de evolução com flags de experimento e reversão
Melhorar
Executar um ciclo de melhoria manual em traces ou prompts selecionados
Modelo dialético
Configurações do modelo revisor para crítica e refinamento
Configurações
Ativar/desativar módulos, filtros de trace, cadência, notificações e o que cada revisor procura
Logs de execução
Histórico de cada execução de evolução com status, custo e artefatos
O que cada revisor procura
Quatro revisores de IA leem as respostas mais recentes de um bot — os revisores de padrão, velocidade, qualidade de resposta e entrada — e cada um trabalha a partir de um briefing. Em Agent Evolution → Configurações → Revisões, você pode alterar o briefing de um revisor para o bot: as coisas que ele procura, uma por linha, e para dois deles um número — quantas respostas um padrão precisa antes de ser relatado (2 para começar) e quanto tempo uma etapa pode levar antes de contar como lenta (2.000 ms para começar). Como um revisor relata o que encontra permanece fixo: seu briefing é entregue a ele ao lado das respostas, nunca como suas instruções. Um padrão que cita menos respostas do que o briefing pede é deixado de lado, e o revisor de velocidade vê o tempo de cada etapa. Somente o que você altera é salvo, então Usar o briefing padrão traz de volta o próprio briefing da Rylvo. Cada revisão — iniciada no painel, após uma execução de falhas ou após um chat na página do bot — é executada nos servidores da Rylvo, com sua própria chave de LLM.
Prompts de autoaperfeiçoamento
Um fluxo de trabalho focado do Agent Evolution para prompts. Ele analisa o desempenho de versões de prompt a partir de traces ao vivo, gera revisões propostas com explicações, avalia-as em traces reservados e publica versões vencedoras como novas versões de prompt (não ativas até você promovê-las). Ele é executado com sua própria chave de LLM (BYOK) e é gratuito.
Cada alteração proposta é controlada por uma flag de experimento com critérios de sucesso mensuráveis. Qualquer coisa que não mova a agulha é revertida automaticamente; qualquer coisa que mova se torna uma alteração versionada permanente que você pode inspecionar, bifurcar ou reverter.
Painel do Agent Skills (somente dashboard)
Pacotes de capacidade reutilizáveis que estendem seus bots
Skills são instruções reutilizáveis e versionadas que um bot segue somente quando a mensagem de um cliente as exige. Uma skill é acionada quando a mensagem contém uma de suas palavras ou uma de suas frases como escritas (ou em cada resposta, quando não tem nenhuma), e suas instruções são adicionadas ao prompt do sistema do bot para aquela resposta. Skills fazem parte do Pro e superiores e são executadas para um bot assim que o interruptor de Skills está ativado. Escreva as suas, adicione uma da biblioteca, importe-as ou revise as sugeridas a partir do que o Agent Evolution aprendeu. Gerencie em Dashboard → Agent Skills.
Skills em produção
- Instruções reutilizáveis — orientam o agente quando uma skill é ativada
- Palavras e frases — decidem a quais mensagens elas se aplicam
- Escopo do bot ou da organização — controlam onde uma skill se aplica
- Versões e telemetria — revisam alterações e uso ao vivo
Correspondência de gatilhos (determinística, sem LLM)
- Uma palavra corresponde em qualquer lugar da mensagem, mesmo dentro de uma palavra mais longa
- Uma frase corresponde como escrita — sua parte entre aspas ou cada parte entre vírgulas (5+ caracteres)
- Uma palavra ou uma frase atinge o mínimo padrão (0,25); no máximo 8 skills por resposta
- Palavras comuns (“pode”, “sobre”, “eles” …) nunca são gatilhos — são descartadas e ignoradas
- Correspondência opcional por significado: similaridade de incorporação com peso 0,3
- Sem palavras e sem frases: adicionada a cada resposta, primeiro
6 fontes de skills
- manual — operador cria via painel
- generated_from_rules — promovida automaticamente de clusters de regras (opt-in)
- imported — importada de outro bot/organização
- architect — criada pelo Workspace Architect
- reviewer_suggested — sugerida pelo mecanismo revisor
- prebuilt — instalada do catálogo da Skill Library
Injeção em tempo de execução e segurança
- Skills correspondentes adicionadas a
BotPromptInputs.skill_instructions - Mescladas no prompt do sistema sob "## ACTIVATED SKILLS"
- Redação que tenta substituir as instruções do bot é recusada ao salvar
- Somente as instruções (e dicas de ferramentas) são enviadas — nunca o nome ou a descrição
- Uso registrado pós-turno via SkillUsageEventDoc
- Confiança: pontuação × 0,9 (sucesso) ou × 0,2 (falha) menos penalidade de guardrail
Escopo e ciclo de vida
- Escopo do bot — botId = bot específico, somente esse bot o carrega
- Todo bot — botId = null, todo bot o carrega
- O tempo de execução carrega primeiro o escopo do bot (prioridade), depois o nível da organização
- Status: rascunho → ativo → desativado → arquivado
- Somente uma skill ativada é usada; Produção usa as cópias lançadas
Versionamento, reversão e promoção automática
- Cada alteração cria um SkillVersionDoc (7 tipos de alteração)
- Colocar uma versão de volta restaura seu texto e gatilhos; ligado/desligado permanece como está; contadores reiniciam
- Reversão automática desativa uma skill com falha e a mantém em Teste e Produção até um administrador liberá-la
- Sugestões de regras aprendidas: opt-in por bot, após cada revisão concluída (cluster ≥ 3, configurável 2–10), sempre como rascunhos
- Eficácia: usageCount, successCount, avgConfidence, lastUsedAt
Limites de RBAC e planos
evolution.edit_config— admin+ (gerenciar skills)- Viewers podem ver, mas não criar/editar/excluir/alterar status/reverter
Pro e Enterprise: skills ilimitadas · Free, Starter e Lite: não incluídas (skills existentes são mantidas)
Páginas do painel
- Todas as skills — quem usa cada uma, o que a aciona, como está indo
- Cada skill — visão geral, instruções, gatilhos, versões, configurações
- Testar uma mensagem — quais skills uma mensagem aciona e o que o modelo recebe
- Biblioteca — 50 skills prontas em 15 categorias
- Configurações — interruptor de Skills de cada bot, correspondência, sugestões, reversão automática
Ative skills para um bot em Skills → Configurações.
Skill Library (Catálogo Predefinido)
Um catálogo selecionado de 50 skills prontas em 15 categorias cobrindo modelos de bot de agente único e multiagente (Suporte ao Cliente, Vendas, Conformidade, Coleta de Dados, Design de Conversa, Conhecimento e Escalação, E-commerce, Saúde, RH e Interno, Finanças e Seguros, TI e Técnico, Multiagente, Conteúdo e Marketing, Imóveis e Educação, Utilitários). Navegue em Skills → Biblioteca e adicione uma cópia a um bot ou a todos os bots.
Modelo de bifurcação
- Instalar cria uma cópia que você possui (
source: "prebuilt") - Sem atualizações automáticas — edite livremente após a instalação
- Como
draftou ativada — você escolhe - Para um bot ou para todos os bots — você escolhe
- Aciona nas frases do catálogo (as curtas como “vip” também se tornam palavras)
Guardrails
- Cada skill da biblioteca pode ser adicionada uma vez por bot e uma vez para todos os bots
- Adicione várias de uma vez — a um bot ou a todos os bots, pulando as que já existem
- Skills instaladas são skills normais — edite, clone, exclua, reverta
Estrutura do Firestore
{envRoot}/agentSkills/{skillId}
|- skillId, orgId, botId (null = org-level), botName
|- name, slug, description, skillType, source, status
|- systemInstructions (max 8000), triggerConditions[], triggerKeywords[]
|- requiredTools[], toolChain[], generatedFromRuleIds[]
|- version, previousVersionId
|- usageCount, successCount, failureCount, avgConfidence, lastUsedAt
+- tags, metadata, createdBy, createdAt, updatedAt
{envRoot}/agentSkills/{skillId}/versions/{versionId}
|- version, changeType, previousInstructions, newInstructions
|- previousStatus, newStatus, changeReason
|- previous/newTriggerConditions, previous/newTriggerKeywords
+- usageCountAtChange, changedBy, createdAt
organizations/{org}/skillSafetyHolds/{skillId}
+- active, reason, failureRate, usageCount, createdAt, releasedAt?
{envRoot}/agentSkills/{skillId}/usageEvents/{eventId}
|- eventId (turnId:skillId), turnId, outcome, confidence, score
+- createdAt, aggregated
Mission Control (somente dashboard)
Supervisão humana ao vivo para cada conversa em produção
O Mission Control é a superfície de operações ao vivo em /dashboard/mission-control. Os operadores veem cada conversa ativa em tempo real, podem intervir em qualquer nível, e o sistema mantém uma trilha de auditoria imutável que atende aos requisitos do Artigo 14 da Lei de IA da UE (supervisão humana). Tempo real via listeners do Firestore onSnapshot (sem WebSocket/SSE).
6 tipos de intervenção
- Sussurro — injeta instrução do sistema (o cliente não vê), injetada no prompt via
fetch_active_whispers - Assunção — operador se torna o respondente, bot pausado
- Pausa — congela o bot, o cliente vê mensagem de espera
- Encerrar — termina a sessão imediatamente, envia fallback (irreversível)
- Retomar — retoma uma conversa pausada/assumida
- Sinalizar — sinaliza para revisão sem interromper
Intervenções bloqueantes (pausa/assunção/encerrar) acionam o pré-gate do mecanismo Python (evaluate_mission_control_gate) que bloqueia o bot de responder. Justificativa necessária para pausa/assunção/encerrar.
Aprovações e SLAs
3 níveis de urgência com tempos limite:
- imediato — tempo limite de 15s (informativo de baixo risco)
- padrão — 120s (acesso a dados, relacionado a PII)
- estendido — 900s (financeiro, jurídico, conformidade)
Ciclo de vida: pendente → aprovado / negado / expirado / auto_negado. ExpiresAt calculado no servidor. Decisões anexadas ao trace.
11 gatilhos de alerta
Por conversa (inline após cada turno do bot):
- risk_score_above, guardrail_blocked, guardrail_triggered_n_times
- conversation_duration_above, no_operator_monitoring, approval_queue_size_above
- pattern_detected (regex), budget_threshold_crossed
Tick do servidor (tarefa agendada a cada minuto):
- bot_turn_failed_n_in_window, byok_key_unhealthy, wallet_balance_below
Severidade: crítico/alto/médio/baixo. Cooldown (padrão 300s). Supressão: adiar + horários de silêncio (fuso IANA). Instâncias de alerta idempotentes via groupKey (ruleId:conversationId).
Presença do operador
- 4 estados: online / ausente / ocupado / offline
- Heartbeat de 30s, obsoleto após 3 min → offline automático
- Rastreamento de turno: shiftStart / shiftEnd
- Capacidade: maxConcurrentMonitors (padrão 5)
- Estatísticas: totalInterventions, totalApprovals, avgResponseTimeMs
- Eleição de líder localStorage entre abas para varredura
Pontuação de risco e conformidade
- Pontuação de risco 0–100, 5 níveis: crítico / alto / médio / baixo / mínimo
- Pesos fixos: guardrail 30, padrão 25, sentimento 20 (listas de palavras-chave em inglês), tópico 15, duração 10
- Além disso, em turnos de canal ao vivo, um sinal
custom(peso 10) do TypeSafe Jev: probabilidades de frustração, urgência e ameaça de cancelamento nos últimos 5 turnos do usuário, não limitado ao inglês. Ele pode adicionar risco, nunca reduzi-lo - Sinais de risco: fonte, nome, pontuação, detalhes, timestamp
- Modos de conformidade: padrão / eu_ai_act / soc2 / hipaa / personalizado
- Log de auditoria de supervisão somente anexação (cada ação do operador)
- Exportação de conformidade (CSV/JSON) com URLs assinadas
- Retenção: baseada no plano (7d/30d/90d/ilimitado), substituível
RBAC
missionControl.view— visualizador+missionControl.intervene— operador+missionControl.resolve_approval— operador+missionControl.ack_alert— operador+missionControl.manage_rules— administrador+missionControl.edit_settings— administrador+missionControl.delete_conversation— administrador+
7 abas do painel
Feed ao vivo
Lista de conversas em tempo real (máx. 100), painel de detalhes com transcrição + intervenções + sinais de risco, ações rápidas, atribuir operador
Alertas
Ativos (confirmação em massa, adiar, resolver), adiados, histórico, CRUD de regras com chips de evidência
Canais
Saúde de conectividade por canal, taxas de erro, fila de novas tentativas
Análises
KPIs, gráficos por tipo/gravidade/status, ranking de operadores (7d/30d/90d)
Log de auditoria
Log de eventos somente anexação, filtros, exportação de conformidade (CSV/JSON)
Operadores
Escala da equipe com status, função, indicador de turno, estatísticas
Configurações
Ativar/desativar, urgência de aprovação, monitoramento automático, modo de conformidade, retenção, mensagens
Endpoints da API
- POST /api/mission-control/intervene — criar intervenção (operador+)
- POST /api/mission-control/revert — reverter intervenção (operador+)
- POST /api/mission-control/alert-rules — criar/atualizar regra de alerta (administrador+)
- POST /api/mission-control/dispatch — enviar mensagem do operador para o canal (operador+)
- POST /api/mission-control/delete-conversation — exclusão definitiva + cascata (administrador+)
Estrutura do Firestore
{envRoot}/liveConversations/{conversationId}
|- botId, conversationId, status, riskScore, riskLevel
|- riskSignals[], messageCount, durationMs, lastMessagePreview
|- guardrailTriggeredCount, assignedOperatorId, monitoringOperatorIds[]
|- channel, isProduction, tags, flaggedReason
+- startedAt, lastMessageAt, endedAt
{envRoot}/operators/{uid}
|- status: online/away/busy/offline, maxConcurrentMonitors
|- totalInterventions, totalApprovals, avgResponseTimeMs
+- shiftStart, shiftEnd, lastActiveAt
{envRoot}/interventions/{interventionId}
|- type, operatorId, rationale, payload, outcome
|- riskScoreAtTime, messageCountAtTime, idempotencyKey
+- createdAt, resolvedAt
{envRoot}/approvalRequests/{requestId}
|- actionType, urgency, timeoutSeconds, status
|- riskScoreAtTime, riskSignals[], conversationContext
+- requestedAt, expiresAt, resolvedBy, resolvedAt
{envRoot}/alertRules/{ruleId}
|- trigger, severity, config, botId, notificationChannelIds[]
|- cooldownSeconds, snoozedUntil, quietHours
+- lastTriggeredAt, triggerCount
{envRoot}/alertInstances/{alertId}
|- ruleId, status, groupKey, fireCount, evidence[]
+- firstFiredAt, lastFiredAt, acknowledgedAt, resolvedAt
{envRoot}/oversightAudit/{entryId}
|- eventType, operatorId, conversationId, botId
+- details, riskScoreAtTime, timestamp
{envRoot}/missionControl/config
|- enabled, defaultApprovalUrgency, autoMonitorHighRisk
|- complianceMode, auditRetentionDays, maxOperatorsPerConversation
+- pauseMessage, takeoverMessage
Fluxos
Grafos de conversa guiados/estritos que conduzem um bot por uma sequência de etapas — cada etapa carrega um objetivo (injetado no prompt do sistema), dados a coletar, um escopo de ferramentas permitidas e transições que o mecanismo avança conforme a conversa progride. Os fluxos são limitados à organização, anexados a um bot via bot.flowId ou a um grupo de agentes via group.flowId, avaliados por turno pelo mecanismo, e não fazem parte da solicitação ou resposta /api/v1/bot-run. Em todos os planos — Gratuito inclui 1 fluxo, Lite 10, Pro e superiores ilimitados.
Documento de fluxo (FlowDoc)
name,descriptionmode: guiado | estritostart_step_id: etapa de entrada (deve ser definida)steps: FlowStep[]enabled: booleano
Estrutura de etapa (FlowStep)
id(único),namegoal: injetado no prompt do sistema para esta etapacollect: informações a solicitar antes de avançar — o fluxo mantém o que a coleta de dados do bot não consegue salvarallowed_tools: string[] | "all" | "none" — aplicado no modo estrito, orientação no guiadoallowed_agent_id: subagente para esta etapa (grupos)terminal: encerra o fluxo
Transição
to: id da etapa de destinokind: sempre | dados_completos | intenção | condição | resultado_da_ferramentaintent(tipo=intenção),expr(tipo=condição)tool(tipo=resultado_da_ferramenta): dispara quando executada com sucesso neste turno
Estado de execução (FlowState)
flow_id,current_step_idvisited: ids de etapas vistos nesta sessãodone: o fluxo atingiu uma etapa terminaldata: respostas que o fluxo manteve (mascaradas nas respostas)turns,step_turns: turnos no fluxo / nesta etapa- Um FlowState por sessão, avançado a cada turno; removido após 90 dias de inatividade
Validação do grafo
- Pelo menos uma etapa; ids de etapas únicos
- start_step_id deve ser uma etapa definida
- Todo destino de transição deve existir
- intenção / condição / resultado_da_ferramenta carregam seu campo
- Todas as etapas alcançáveis a partir do início (BFS)
Anexação a bot e grupo
- Bot:
bots/{botId}.flowId - Grupo:
agentGroups/{groupId}.flowId - Anexar via
/attachpara que o campo não seja descartado pelo caminho de escrita do modelo - O mecanismo lê flowId do documento bruto a cada turno
Execução em tempo de execução (por turno)
- 1. Ler flowId e carregar o fluxo (flow_loader.load_flow)
- 2. Resolver o FlowState da sessão (iniciar no primeiro turno)
- 3. Injetar o objetivo da etapa e o que ainda falta; o modo estrito limita allowed_tools
- 4. Salvar cada resposta — no perfil, ou mantida pelo fluxo quando o bot não consegue salvá-la
- 5. advance() avalia transições e move para a próxima etapa
- 6. Uma etapa terminal marca o fluxo como concluído
Versionamento
- Cada atualização tira um instantâneo da revisão anterior
GET .../versionslista revisões anteriores- Restaurar = carregar uma revisão no editor e Salvar
- Melhor esforço — uma falha de instantâneo nunca bloqueia o salvamento
Limites do plano
- Todo plano tem fluxos — apenas novos são limitados (
max_flows) - Gratuito: 1 fluxo · Starter: 3 · Lite: 10
- Pro / Enterprise: ilimitados
- Editar um fluxo existente nunca é bloqueado
RBAC
- Leitura: qualquer membro da organização
- Criar / Atualizar / Excluir / Anexar: requer o recurso de fluxos
- Todos os endpoints executam authorize_org (associação à organização)
- Escrito apenas via engineFetch — nunca diretamente no Firestore
Endpoints da API (Python FastAPI, interno)
- POST /v1/flows/{company_id} — criar fluxo (valida o grafo)
- GET /v1/flows/{company_id} — listar ({ flows, total })
- GET /v1/flows/{company_id}/{flow_id} — obter um único
- PUT /v1/flows/{company_id}/{flow_id} — atualizar (tira instantâneo da revisão anterior)
- GET /v1/flows/{company_id}/{flow_id}/versions — listar revisões
- DELETE /v1/flows/{company_id}/{flow_id} — excluir
- POST /v1/flows/{company_id}/{flow_id}/attach — vincular a bot ou grupo
- POST /v1/flows/{company_id}/detach — desvincular de bot ou grupo
Todos os endpoints exigem authorize_org(request, company_id). Mutações exigem um administrador ou proprietário; criações contam contra max_flows. Interno (gerenciado pelo painel), não REST público.
Estrutura do Firestore
{envRoot}/flows/{flowId}
|- name, description
|- mode: guided | strict
|- start_step_id: string
|- steps: [{ id, name, goal, collect[],
| allowed_tools, allowed_agent_id?,
| transitions: [{ to, kind, intent?, expr?, tool? }],
| terminal }]
+- enabled: bool
{envRoot}/bots/{botId}
+- flowId: string | null
{envRoot}/agentGroups/{groupId}
+- flowId: string | null
Detalhes rastreados (estado)
Detalhes tipados que um bot lembra e mantém atualizados enquanto conversa — configure-os em Bots → seu bot → Memória. Cada detalhe é lembrado para esta conversa, esta pessoa (em todas as conversas dela) ou todos (um valor compartilhado). O bot os vê no prompt e os altera com sua ferramenta update_state; prompts usam {{state.key}}; seus sistemas leem e alteram com a API abaixo. Cada alteração é uma revisão que você pode restaurar. O esquema é editado em Teste e liberado para Produção como o resto do bot; valores são dados de tempo de execução em cada ambiente.
Tipos e comportamento de atualização
- texto, número, booleano, data (ISO 8601), escolha, lista (de textos, números ou objetos), objeto
replace,keep_first— qualquer tipoincrement,max,min— números (máx/mín também datas)append,append_unique— listasmerge— objetos (RFC 7396: um null remove uma chave)- Regras opcionais: intervalo numérico, comprimento e padrão de texto, tamanho de lista, JSON Schema (Draft 2020-12) para objetos
API
Use uma chave de API com o escopo state:read ou state:write. A organização e o ambiente da chave se aplicam; uma chave restrita a um bot alcança apenas esse bot. O sujeito é um id de conversa (session), seu id de usuário final (person) ou shared (bot).
| GET | /api/v1/state/{botId}/config | Os detalhes rastreados do bot |
|---|---|---|
| GET | /api/v1/state/{botId}/records?scope=&limit= | Registros alterados recentemente |
| GET | /api/v1/state/{botId}/records/{scope}/{subjectId} | Valores de um registro |
| PATCH | /api/v1/state/{botId}/records/{scope}/{subjectId} | Alterar valores (atômico; tudo ou nada) |
| GET | /api/v1/state/{botId}/records/{scope}/{subjectId}/revisions | Histórico, mais recente primeiro |
| POST | /api/v1/state/{botId}/records/{scope}/{subjectId}/restore | Restaurar uma revisão (como uma nova) |
| DELETE | /api/v1/state/{botId}/records/{scope}/{subjectId} | Excluir um registro e seu histórico |
| PUT | /api/v1/state/{botId}/config | Substituir o esquema (chaves de Teste) |
curl -X PATCH https://rylvo.com/api/v1/state/bot_123/records/person/user_42 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-shipped-9921" \
-d '{
"ops": [
{ "field": "plan", "op": "replace", "value": "pro" },
{ "field": "orders", "op": "update", "value": 1 },
{ "field": "coupon", "op": "clear" }
],
"expectedRevision": 7
}'
update aplica o comportamento de atualização do detalhe, replace define o valor exato, clear o remove. values é uma abreviação para um update por chave. expectedRevision faz a escrita falhar com 409 (e a revisão atual) se algo mudou desde que você leu; um valor recusado é um 422 com um motivo por campo. Respostas executadas pelo bot incluem o state e o stateEvents do turno quando a chave tem um escopo de estado.
Conversas: regras e transferência
Iniciar uma nova conversa quando…
- Uma regra observa um detalhe de conversa ou pessoa: ele se torna um valor, muda, é definido ou é limpo
- Dispara uma vez, na mudança — não enquanto o valor permanece o mesmo
- Alterado pelo bot: a conversa termina após a resposta (o bot é informado, então ele encerra)
- Alterado por seus sistemas ou um colega: a conversa aberta da pessoa termina; a resposta diz quantas (
sessionsEnded) - A próxima mensagem da pessoa inicia uma nova conversa; rastros mostram a regra
Transferir para a próxima conversa
- Detalhes de conversa começam vazios em cada nova conversa
- Marque um para transferir e a próxima conversa começa com seu último valor (ex.: o pedido sendo tratado)
- Copiado uma vez, antes da primeira resposta, como sua própria revisão — nunca sobre um valor já existente
- Detalhes de pessoa são sempre mantidos entre conversas
Memória além das últimas mensagens
Em Bots → seu bot → Sessões, a janela de memória define quantas mensagens recentes uma resposta carrega. Um orçamento de tokens também as mantém dentro desse número de tokens, mais recentes primeiro, para que algumas mensagens longas não excluam o resto. Resumir mensagens mais antigas dobra mensagens que saem da janela em um resumo contínuo que o bot vê em cada turno — atualizado após respostas, a cada poucas mensagens, no modelo próprio do bot. Rastros mostram quando uma resposta usou o resumo ou o orçamento deixou mensagens de fora.
Várias mensagens de uma vez (mensagens duplas)
Em Bots → seu bot → Sessões, escolha o que acontece quando alguém envia outra mensagem enquanto o bot ainda está respondendo:
- Responder em ordem (padrão) — uma resposta por vez; a próxima mensagem é respondida após a anterior, tendo-a em mente
- Esperar e responder juntas — espera um momento (1–15 s) após a última mensagem e responde mensagens rápidas em uma única resposta; fotos e notas de voz nunca são mescladas (na API e no Beam, mensagens são respondidas em ordem)
- Responder apenas a primeira — mensagens enviadas durante a resposta recebem um aviso curto nos canais; a API responde
409 conversation_busycomRetry-After - Responder cada uma imediatamente — sem coordenação; respostas podem se sobrepor
A coordenação é por usuário final e conversa, em todos os servidores. Nunca perde uma mensagem: uma mensagem de canal que esperou 45 segundos é respondida mesmo assim, e uma chamada de API espera até 25 segundos antes de conversation_busy. Chamadas sem endUserExternalId não são coordenadas.
Contexto de execução
Envie fatos que seu aplicativo conhece com uma mensagem — o plano da pessoa, a página em que ela está — como context na execução do bot (um objeto JSON, até 16 KB). O bot o vê apenas para essa mensagem, prompts usam {{context.plan}} ou {{context.account.tier}}, e nada é armazenado — rastros mantêm apenas os nomes das chaves. Defina um JSON Schema em Memória → Contexto de execução e uma solicitação que não corresponde recebe um 422 com os motivos em details.problems, antes de o bot executar. Contexto enviado do widget é ignorado.
curl -X POST https://rylvo.com/api/v1/bot-run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"botId": "bot_123",
"endUserExternalId": "user_42",
"message": "Can I add a seat?",
"context": { "plan": "pro", "seats": 4, "page": "/billing" }
}'
Memória de longo prazo
Detalhes rastreados são campos que você define. Memória de longo prazo é tudo o mais que vale a pena saber na próxima vez — as preferências de uma pessoa, a situação dela, o que aconteceu — mantido como frases curtas que o bot lê quando importam. Ative isso na aba Memória do bot (Teste e depois publique).
- Sobre cada pessoa — mantido em todas as conversas dela com o bot (precisa de
endUserExternalId). Compartilhada — verdadeira para todos, como um caderno de equipe; novas memórias compartilhadas que o bot salva podem aguardar a revisão de um colega. - Como são criadas — o bot salva e corrige enquanto conversa (suas ferramentas
remembereforget), e após uma conversa terminar, uma IA lê e salva o que vale a pena lembrar, seguindo suas instruções. Seu aplicativo e colegas também podem adicioná-las. - Como são usadas — a cada mensagem, o bot recebe as memórias mais próximas em significado (fixadas primeiro), até o número que você escolher; ele pode pesquisar o restante.
- Manutenção — uma nova memória que diz o que uma existente já diz a atualiza em vez disso; as memórias de uma pessoa podem ser esquecidas após dias sem uso; apagar uma pessoa remove as memórias dela em todos os lugares.
| GET | /api/v1/memory/{botId}/memories?scope=person&subjectId=… | As memórias de uma pessoa (ou scope=shared) |
|---|---|---|
| POST | /api/v1/memory/{botId}/memories | Lembrar algo |
| PATCH | /api/v1/memory/{botId}/memories/{memoryId} | Corrigir, fixar, marcar ou aprovar |
| DELETE | /api/v1/memory/{botId}/memories/{memoryId} | Excluir uma |
| POST | /api/v1/memory/{botId}/search | Pesquisar por significado |
| DELETE | /api/v1/memory/{botId}/people/{subjectId} | Esquecer tudo sobre uma pessoa |
# Tell the bot something about a customer, from your backend
curl -X POST https://rylvo.com/api/v1/memory/bot_123/memories \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"scope": "person", "subjectId": "user_42", "text": "Upgraded to the Pro plan on 3 Oct 2026.", "kind": "event"}'
# What does the bot remember about their billing?
curl -X POST https://rylvo.com/api/v1/memory/bot_123/search \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"query": "billing and plan", "subjectId": "user_42"}'
Use uma chave com memory:read ou memory:write. Com memory:read, respostas executadas pelo bot também carregam memory: as memórias que o bot recebeu e o que ele alterou. Um espaço cheio responde 409; quando a memória de longo prazo está desativada, gravações respondem 422.
Código personalizado
Execute seu próprio código em cinco pontos de cada conversa, na aba Código do bot (Teste e depois publique): no seu servidor — Rylvo envia JSON via POST para seu endpoint HTTPS, assinado — ou na Rylvo — você escreve um módulo JavaScript e a Rylvo o executa em uma sandbox (nova a cada chamada, seu limite de tempo, 32 MB, fetch apenas para hosts que você permitir, segredos como ctx.secrets.NAME). De qualquer forma, a Rylvo usa o que você responder. Cada campo de uma resposta é opcional — um {} vazio não muda nada.
| Estágio | Quando | Você pode responder |
|---|---|---|
| on_session_start | Primeira mensagem de uma conversa | contexto, instruções, estado |
| before_turn | Cada mensagem, antes do modelo | contexto, instruções, estado, resposta, bloqueio |
| retrieve | Cada mensagem, junto com a base de conhecimento | passagens |
| after_turn | Após o bot responder, antes do envio | resposta, estado, endConversation |
| on_session_end | Uma conversa terminou (repetida) | — (resposta ignorada) |
context— fatos que o bot vê para esta mensagem (entra no contexto da execução);instructions— regras extras para esta resposta.state— valores de detalhes rastreados para salvar, como seus sistemas (o gravador da API), ex.:{"plan": "pro"}.reply— responda você mesmo (sem chamada de modelo) ou, após o turno, substitua a resposta do bot;block— recuse com sua mensagem.passages— até 10{title, text, url?, score?}nos quais o bot baseia sua resposta, citados como trechos da base de conhecimento.endConversation—trueou{"reason": "…"}: a próxima mensagem da pessoa inicia uma nova conversa.
// What your endpoint receives (before_turn)
{
"stage": "before_turn", "deliveryId": "msg_…", "test": false,
"bot": { "id": "bot_123", "name": "Support" }, "environment": "production",
"conversation": { "id": "conv_8f2a91", "channel": "widget" },
"person": { "id": "user_42" },
"message": { "text": "Where is my order A-1042?" },
"transcript": [{ "role": "user", "text": "Hi" }, { "role": "assistant", "text": "Hello!" }],
"state": { "session": { "order_id": null }, "person": { "plan": "free" } },
"context": { "page": "/orders" }
}
As chamadas são assinadas com o segredo de assinatura do bot (um por ambiente, na aba Código) usando o esquema Standard Webhooks — webhook-id, webhook-timestamp, webhook-signature — para que qualquer biblioteca Standard Webhooks as verifique. Responda dentro do limite de tempo do estágio (500 ms–10 s); quando seu endpoint falhar, o bot continua sem ele ou — se você escolheu isso para before/after — envia sua mensagem de fallback. Endereços internos nunca são chamados. Cada chamada aparece como uma etapa "Seu código" no trace.
// On Rylvo: the whole stage is this module
export default async function (event, ctx) {
const r = await fetch("https://api.yourshop.com/orders?person=" + event.person?.id, {
headers: { authorization: "Bearer " + ctx.secrets.SHOP_KEY },
});
const [order] = await r.json();
return order ? { context: { order_status: order.status, eta: order.eta } } : {};
}
No seu servidor, verifique a assinatura primeiro:
import { Webhook } from "standardwebhooks";
const wh = new Webhook(process.env.RYLVO_SIGNING_SECRET); // whsec_…
app.post("/rylvo/stage", express.raw({ type: "application/json" }), (req, res) => {
const event = wh.verify(req.body, req.headers); // throws if forged or stale
if (event.stage === "before_turn" && /order/i.test(event.message.text)) {
const order = lookUpOrder(event.person?.id);
return res.json({ context: { order_status: order.status, eta: order.eta } });
}
res.json({});
});
API de Sessões
As conversas de um bot, para seu backend: liste e pesquise — por pessoa, por status de encerramento ou por detalhes rastreados — leia uma com sua transcrição, encerre uma ou bifurque uma em uma cópia para continuar. Use uma chave de API com o escopo sessions:read ou sessions:write; uma chave restrita a um bot alcança apenas esse bot.
| GET | /api/v1/sessions?botId=… | Mais recentes primeiro; endUserExternalId, status=open|ended, state.<key>=<value>, limit, before |
|---|---|---|
| GET | /api/v1/sessions/{sessionId}?botId=… | A conversa e sua transcrição |
| POST | /api/v1/sessions/{sessionId}/end | Encerra; a próxima mensagem da pessoa inicia uma nova |
| POST | /api/v1/sessions/{sessionId}/fork | Uma cópia com a transcrição e detalhes rastreados |
# Open conversations about a refund
curl "https://rylvo.com/api/v1/sessions?botId=bot_123&status=open&state.issue_type=Refund" \
-H "Authorization: Bearer YOUR_API_KEY"
# End one, leaving a note the next conversation can carry
curl -X POST https://rylvo.com/api/v1/sessions/conv_8f2a91/end \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"botId": "bot_123", "note": "Refund issued; tracking number sent."}'
# Fork it from an earlier point to try a different reply
curl -X POST https://rylvo.com/api/v1/sessions/conv_8f2a91/fork \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"botId": "bot_123", "throughMessageId": "m_41", "stateRevision": 3}'
Uma bifurcação não tem canal próprio, então nada alcança ninguém até você enviar uma mensagem com execução do bot e seu sessionId — com o mesmo usuário final, ela se torna a conversa atual dele. Encerrar é idempotente; a nota se torna o resumo de fechamento, levado para a próxima conversa quando a continuidade do bot é "perfil + resumo".
DatasetsSomente painel
Datasets são coleções curadas de traces ou perfis de usuários finais para análise, revisão e colaboração em equipe. Gerencie em Painel → Datasets.
Datasets de trace
Fixem traces canônicos em uma coleção compartilhada para depuração, testes de regressão ou revisão qualitativa.
- Fixe na página de Traces ou navegue por traces não fixados dentro do dataset
- Origem do trace:
canonical,legacyoudashboard - Replay de trace inline + painel de detalhes
- Thread de comentários compartilhado com a página de Traces
- Arquivamento suave ou exclusão definitiva de um dataset
Datasets de pessoas
Agrupe perfis de usuários finais para segmentação, revisão de coorte ou exportação.
- Colete perfis de usuários finais do Audience
- Visualização de detalhes somente leitura por perfil
- Reutilize para segmentação de público de transmissão
Retenção e cotas
| Plano | Máx. de datasets | Máx. de traces preservados |
|---|---|---|
| Free | 1 | 50 |
| Starter | 1 | 200 |
| Lite | 10 | 5.000 |
| Pro | 50 | 25.000 |
| Enterprise | ∞ | ∞ |
Permissões
- Viewer+ — visualizar datasets
- Operator+ — criar, editar, arquivar, fixar/desfixar traces
- Admin — excluir definitivamente o dataset e todos os itens fixados
Excluir um dataset remove as fixações e o documento do dataset. Os traces fixados em si ficam então sujeitos à política normal de retenção da organização, então exclua com cuidado.
Entrega de e-mailSomente painel
A Rylvo gerencia seus próprios e-mails transacionais (boas-vindas, convites de equipe, relatórios agendados, alertas operacionais) automaticamente. Os modelos são personalizados e conscientes do tema — não há nada para você configurar.
Para enviar seus próprios e-mails em eventos de fluxo de trabalho (ex.: notificar um humano quando uma sessão escalar), use um Event Connector ou adicione um canal de E-mail em Automação.
Clientes OAuthSomente painel
Servidor de autorização OAuth 2.1 servidor-para-servidor para autenticação de clientes MCP (Model Context Protocol). Permite que editores de IA (Claude Code, Cursor, Windsurf, Zed) autentiquem com a Rylvo e acessem a API de ferramentas MCP. Implementa RFC 6749, 7636 (PKCE), 7591 (DCR), 7009 (revogação), 7662 (introspecção), 8414 (metadados), 8707 (vínculo de público), 9728 (recurso protegido). Gerencie em Painel → Integrações.
Documento de registro de cliente
clientId: "client_" + 12 caracteres base64url aleatóriosclientName(1-200),redirectUris[]grantTypes: authorization_code, refresh_tokentokenEndpointAuthMethod: none | client_secret_postclientSecretHash: hash SHA-256 (nulo para clientes públicos)- Coleção global (não limitada à organização); segredo em texto puro nunca é persistido
Tipos de cliente e gerenciamento de segredos
- Público (somente PKCE): nenhum segredo emitido,
authMethod="none" - Confidencial: segredo base64url aleatório de 32 bytes,
authMethod="client_secret_post" - Segredo retornado UMA VEZ na resposta DCR; apenas o hash SHA-256 é armazenado
- Comparação em tempo constante (
timingSafeEqual) previne ataques de temporização
Tipos de concessão e fluxo de token
- Código de Autorização (PKCE obrigatório): authorize → consent → troca de token
- Rotação de Refresh Token: transação atômica no Firestore (revoga antigo, emite novo)
- ID da organização embutido no token autodescritivo:
rfr_{base64url(orgId)}~{random} - Proteção CSRF: HMAC-SHA256 no formulário de consentimento
Tempos de vida do token
- Token de acesso: 24 horas (JWT RS256, vinculado ao público
https://rylvo.com/mcp) - Refresh token: 30 dias com janela deslizante (rotacionado a cada uso)
- Teto da família de refresh tokens: 365 dias absolutos
- Código de autorização: 10 minutos
Escopos (3)
rylvo:read— visualizar bots, análises, conversas, KBrylvo:write— criar/atualizar bots, prompts, conhecimento, configuraçõesrylvo:admin— gerenciar configurações da organização, membros, integrações- Padrão: "rylvo:read rylvo:write"
Recursos de segurança
- Assinatura JWT RS256 com versionamento de chave (OAUTH_JWT_PRIVATE_KEY_PEM em produção)
- PKCE S256 obrigatório (plain rejeitado em produção)
- Vínculo de público (RFC 8707) previne ataques de deputado confuso
- Vínculo de ambiente: uma concessão autoriza um ambiente, escolhido no consentimento e carregado no token; refresh não pode renegociá-lo
- Cabeçalhos: HSTS, X-Frame-Options DENY (widget exceto), CSP report-only
- Rastreamento de JTI revogado: Firestore + LRU em memória (máx. 10 mil)
Estratégia de cache
- Metadados do cliente: TTL de 5 min, máx. 5.000 entradas
- Validação JWT: negativa (spam de 5s) + positiva (ciente de revogação de 2s), máx. 10 mil cada
- Sessão Firebase: TTL de 30s, máx. 2.000 entradas
- Revogação JTI: LRU em memória, máx. 10.000 entradas
RBAC e limites do plano
oauthClients.view— viewer+ (todos os membros)oauthClients.revoke— admin+ (admin ou proprietário)- Coleções OAuth são somente servidor (gravações Admin SDK)
- NÃO limitado por plano — disponível para todos os planos (free → enterprise)
- Filtros de revogação
oauthRefreshTokens.clientIdpor coleção — índice automático de campo único cobre isso
Endpoints da API (padrão OAuth 2.1)
- GET /.well-known/oauth-authorization-server — metadados RFC 8414 (30/min por IP)
- GET /.well-known/jwks.json — JWKS RFC 7517
- GET /oauth/authorize — endpoint de autorização (HTML de consentimento, 30/min por IP)
- POST /oauth/authorize/consent — envio de consentimento (15/min por usuário)
- POST /oauth/token — endpoint de token (10/min por client_id)
- POST /oauth/register — Registro Dinâmico de Cliente (5/min por IP)
- POST /oauth/revoke — revogação de token (10/min por IP)
- POST /oauth/introspect — introspecção de token (30/min por IP)
Painel: GET /api/v1/oauth-clients/{orgId} (lista), POST /api/v1/oauth-clients/{orgId}/{clientId}/revoke (admin+).
Estrutura do Firestore
oauthClients/{clientId} (global, not org-scoped)
|- clientId, clientName (1-200), redirectUris[]
|- grantTypes[], tokenEndpointAuthMethod, scope
|- clientSecretHash (SHA-256 | null for public)
+- createdAt: number (unix seconds)
oauthAuthCodes/{codeHash} (keyed by SHA-256 hash)
|- orgId, userId, clientId, redirectUri, scope
|- codeChallenge, codeChallengeMethod
|- expiresAt (10 min TTL), used, consumedAt?
+- createdAt
environmentRoot(orgId, environment)/oauthRefreshTokens/{tokenHash}
organizations/{orgId}/oauthRefreshTokens/{tokenHash} (unbound legacy)
|- userId, clientId, scope
|- environment: test | production | null (grant binding)
|- expiresAt (30d sliding), familyMaxExpiresAt (365d ceiling)
|- revoked, revokedAt?
+- createdAt
Token format: rfr_{base64url({o:orgId,e:environment})}~{random}
organizations/{orgId}/oauthRevokedJtis/{jti}
|- revokedAt
+- expiresAt (24h, access token TTL)
TTL policies REQUIRED: authCodes (10m), refreshTokens (30d), revokedJtis (24h)
Conectores de Webhook
Conectores permitem que a Rylvo chame seus sistemas durante a execução do fluxo de trabalho. Registre endpoints de webhook para chamadas de ferramentas, sincronização de estado ou notificações de eventos — a Rylvo gerencia autenticação, repetição e assinatura.
Três tipos de conector
Ferramenta
Execute ações em seus sistemas (criar caso, consultar pedido, verificar estoque)
Sincronização de Estado
Leia/grave o estado do fluxo de trabalho no seu banco antes e depois de decisões
Evento
Receba notificações sobre escalonamento, mudança de estágio, falha de verificação
Registrar um conector de ferramenta
curl -X POST https://rylvo.com/api/v1/connectors \
-H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{
"company_id": "comp_001",
"connector_type": "tool",
"name": "Salesforce Case Creator",
"auth": {
"auth_type": "api_key",
"api_key_header": "X-Salesforce-Key",
"api_key_value": "your_salesforce_api_key"
},
"tool_config": {
"tool_name": "create_salesforce_case",
"tool_description": "Create a case in Salesforce",
"input_schema": { "type": "object", "properties": { "issue_summary": { "type": "string" } } }
},
"endpoint": { "url": "https://your-app.com/rylvo/tools/create-case", "method": "POST" }
}'
Endpoints da API
| Método | Caminho | Descrição |
|---|---|---|
| POST | /v1/connectors | Criar conector |
| GET | /v1/connectors/{company_id} | Listar conectores |
| GET | /v1/connectors/{company_id}/{id} | Obter detalhes |
| PATCH | /v1/connectors/{company_id}/{id} | Atualizar |
| DELETE | /v1/connectors/{company_id}/{id} | Excluir |
| POST | .../{id}/activate | Ativar |
| POST | .../{id}/deactivate | Desativar |
| POST | .../{id}/test | Testar endpoint |
| POST | /v1/connectors/generate-secret | Gerar segredo HMAC |
| GET | /v1/connectors/{company_id}/tools/available | Listar ferramentas de webhook |
7 métodos de autenticação
noneapi_keybearer_tokenhmac_sha256basicoauth2_client_credentialscustom_header
11 tipos de eventos assináveis
lead.capturedworkflow.decision.completedworkflow.decision.failedworkflow.escalation.triggeredworkflow.stage.changedtool.execution.completedtool.execution.failedstate.updatedverification.failedsession.startedsession.closed
Envie cada lead para seu CRM
Quando um assistente captura um endereço de e-mail ou número de telefone, o Rylvo registra o lead, envia e-mail aos proprietários do workspace e dispara lead.captured para cada conector de eventos que esteja inscrito nele. Crie um conector Event, marque Lead Captured e cole a URL de um "Catch Hook" do Zapier, um webhook personalizado do Make, um nó Webhook do n8n ou um gatilho de webhook de entrada do GoHighLevel. Mapeie os campos uma vez; cada novo lead chega lá como um contato.
{
"event_id": "evt_lead_…", // stable per lead — dedupe on it
"event_type": "lead.captured",
"bot_id": "…",
"data": {
"lead_id": "…",
"email": "casey@example.com",
"phone": null,
"name": "Casey Morgan",
"fields": { "email": "…", "full_name": "…", "need": "…" },
"first_message": "Do you do implants?",
"bot_name": "Acme Dental Assistant",
"channel": "widget",
"conversation_id": "…",
"lead_url": "https://rylvo.com/dashboard/leads",
"captured_at": "2026-09-23T10:00:00.000Z"
}
}
As entregas são assinadas (Standard Webhooks), com tentativas de reenvio e possibilidade de reprodução a partir do log de entrega do conector. Leads capturados no ambiente de Teste nunca são entregues.
SDK Python do Conector
Métodos de conveniência tipados para todas as operações de conector. Variantes síncronas e assíncronas incluídas.
from core.connectors.sdk import ConnectorSDK
sdk = ConnectorSDK(base_url="https://rylvo.com", api_key="rylv_...")
# Register a tool connector
connector = sdk.create_tool_connector(
company_id="comp_001",
name="Salesforce Case Creator",
endpoint_url="https://your-app.com/rylvo/tools/create-case",
tool_name="create_salesforce_case",
tool_description="Create a case in Salesforce",
auth_type="api_key",
api_key_header="X-Salesforce-Key",
api_key_value="your_salesforce_api_key",
)
# Test + activate
test = sdk.test_connector("comp_001", connector["connector_id"])
if test["success"]:
sdk.activate("comp_001", connector["connector_id"])
# List available tools
tools = sdk.list_available_tools("comp_001")
print(f"{tools['total']} webhook tools available")
Variante assíncrona
from core.connectors.sdk import AsyncConnectorSDK
async with AsyncConnectorSDK(base_url="...", api_key="...") as sdk:
connector = await sdk.create_event_connector(
company_id="comp_001",
name="Slack Alerts",
endpoint_url="https://hooks.slack.com/...",
event_types=["workflow.escalation.triggered"],
)
await sdk.activate("comp_001", connector["connector_id"])
Tratamento de erros
ConnectorNotFoundError (404)O conector não existe
ConnectorAuthError (401/403)Chave de API inválida ou ausente
ConnectorValidationError (422)Configuração de conector inválida
ConnectorSDKError (5xx)Classe base para todos os erros do SDK
CanaisSomente no painel
Configuração de implantação de bot multicanal. 13 tipos de canal suportados — implante seu bot em widgets de site, WhatsApp, Slack, Telegram, Discord, MS Teams, Messenger, Instagram, SMS, LINE, E-mail ou webhooks personalizados. Várias configurações por bot são permitidas, mas apenas uma habilitada por tipo de canal. Inclui monitoramento de saúde, criptografia de segredos, idempotência de webhook e proteção contra condições de corrida. Gerencie em Painel → Implantar.
13 tipos de canal
- widget — Chat do site (origens, cor de destaque, saudação, posição, marca)
- whatsapp — Meta Cloud API (phoneNumberId, verifyToken)
- slack — (teamId, botUserId, signingSecret, channels[])
- telegram — (botId, webhookSecret, allowedChatIds, collectFeedback)
- discord — (applicationId, publicKey, guildId, commandName)
- msteams — (appId, appPasswordPrefix, tenantId)
- messenger — (pageId, verifyToken, appSecretPrefix)
- instagram — (igUserId, verifyToken, appSecretPrefix)
- sms_twilio — (accountSid, fromNumber, messagingServiceSid?)
- whatsapp_twilio — (mesmo que SMS, o conector adiciona o prefixo whatsapp:)
- line — (channelId, channelSecret, channelAccessToken, botUserId)
- email_inbound — (inboxAddress, fromAddress, replyMode, Resend)
- custom — (inboundSecret, label?)
Máquina de estados do status de configuração
- needs_setup → verified, deprecated (incompleto; não pode ser habilitado)
- verified → live, deprecated (teste aprovado; pode ser habilitado)
- live → verified, deprecated (habilitado e recebendo)
- deprecated → verified, needs_setup (restaurável)
enabledpermitido apenas quando setupStatus estiver em [verified, live]- O primeiro teste bem-sucedido promove automaticamente para live (se nenhum canal irmão estiver habilitado)
Regra de um habilitado por tipo
- Aplicada na camada de API via transações do Firestore (
runTransaction) - Ao criar/atualizar com enabled=true: consulta por configuração habilitada existente com o mesmo botId + channelType
- Retorna 409 Conflict se houver duplicata
- As regras do Firestore impõem imutabilidade de
botIdechannelType
Monitoramento de saúde
- Status:
ok|error|idle - 3+ erros consecutivos alteram o status para "error"
- Notificação em leque no primeiro erro e em 3 seguidos; período de espera de 15 min
- Log de eventos somente anexação (últimos 10 eventos, buffer circular) elimina o ponto de acesso RMW
- Rastreia inboundCount, outboundCount, errorCount, consecutiveErrors
Armazenamento e redação de segredos
- Tokens completos em variáveis de ambiente (ex.:
TELEGRAM_BOT_TOKEN_{prefix}) - Tokens criptografados no Firestore como blobs AES-256-GCM
v1: - Prefixos de token (primeiros 8 caracteres) armazenados em texto simples para exibição
- Respostas GET removem campos criptografados antes de enviar ao cliente
- Ordem de resolução: variável de ambiente → Firestore criptografado → texto simples legado
Idempotência de webhook
- Cache de impressão digital de 24 horas em
/dedup/{fingerprint} - Formato:
{channel}:{platform_id}(ex.: telegram:12345) - Tentativas repetidas da plataforma são seguras — duplicatas são confirmadas silenciosamente
- TTL: 24 horas (política TTL do Firestore)
Fluxo de webhook de entrada (14 etapas)
- 1-4: Armazenar corpo em buffer, analisar, confirmação antecipada, verificação de assinatura pré-configuração
- 5-8: Interruptor de emergência, busca de canal, suspensão da organização, limite de taxa por organização (limite de 60 / 120 por minuto)
- 9-12: Confirmação pós-configuração, análise para NormalizedInbound, resolução de sessão, verificação de duplicidade
- 13-14: Registrar entrada, executar turno do bot + enviar resposta (3 tentativas) + registrar saída/erro
- Tudo síncrono dentro da solicitação de webhook (timeout de 15s)
- Caso especial do Discord: retorna type:5 (pensando) imediatamente, executa em segundo plano
RBAC e limites do plano
channels.view— viewer+ (leitura)channels.manage— admin+ (criar/atualizar/excluir)channels.test— operator+ (testar conexão)channels.rotate_secret— admin+ (rotacionar segredos)- Sem limites de canal por plano — ilimitado por plano
- A subcoleção de saúde é somente leitura para clientes (gravações apenas pelo servidor)
Endpoints de API (BFF Next.js)
- POST /api/channels — criar configuração de canal (admin)
- GET /api/channels?orgId=…&botId=…&channelType=…&enabled=… — listar (viewer)
- GET /api/channels/{configId} — obter um único (viewer)
- PATCH /api/channels/{configId} — atualizar (admin)
- DELETE /api/channels/{configId} — excluir (admin)
- POST /api/channels/test — testar conexão (operator)
Endpoints de webhook: /api/channels/{telegram,whatsapp,slack,discord,sms,whatsapp_twilio,line,messenger,instagram,msteams,email_inbound,custom}
Estrutura do Firestore
{envRoot}/botChannelConfigs/{configId}
|- botId (immutable), botName, channelType (immutable)
|- enabled, requireExplicitConsent, defaultConsentScope
|- config: <channel-specific config object>
|- setupStatus: needs_setup | verified | live | deprecated
|- lastTestedAt?, lastVerifiedAt?, apiKeyId?
|- createdBy, createdAt, updatedAt
{envRoot}/botChannelConfigs/{configId}/health/main
|- status: ok | error | idle
|- lastInboundAt, lastOutboundAt, lastErrorAt
|- lastErrorMessage (500 chars max)
|- inboundCount, outboundCount, errorCount, consecutiveErrors
|- recentEvents[]: { ts, kind: inbound|outbound|error, summary } (last 10)
|- updatedAt, lastNotifiedAt?
{envRoot}/botChannelConfigs/{configId}/dedup/{fingerprint}
|- createdAt, expireAt (24h TTL)
{envRoot}/botChannelConfigs/{configId}/health/events/log/{docId}
|- (append-only event log, eliminates RMW hotspot)
{envRoot}/channelMediaAssets/{assetId}
|- expiresAt (max 30 days), GCS blob reference
Entrada de Imagem e VozSomente no painel
Os clientes podem enviar fotos, capturas de tela, documentos e notas de voz, e o bot lê e ouve. A extração roda na sua própria chave de LLM, como o restante da camada de inteligência — não há markup por arquivo.
Como ativar
Está desativado por padrão em todo novo bot. Habilite imagens e áudio por bot no editor de bots e defina regras para todo o workspace em Configurações → Entrada de Mídia: quais tipos de anexo são permitidos, limites de tamanho e duração, o quão rigorosamente os dados pessoais são removidos das transcrições e se os arquivos do cliente podem ser armazenados em repouso.
Onde funciona
Todos os canais implantados — Telegram, WhatsApp (Cloud API e Twilio), Slack, Discord, MS Teams, Messenger, Instagram, LINE, SMS/MMS e E-mail de entrada — além do widget do site, do chat do painel e do parâmetro attachments em /v1/bot-run.
Como cada tipo é lido
- Imagens e capturas de tela — um modelo de visão transcreve o texto visível e descreve o que está na imagem.
- Notas de voz — transcritas para texto e tratadas como qualquer outra mensagem. As respostas são em texto; o bot não fala de volta.
- Documentos — PDFs, Word, PowerPoint e planilhas são lidos a partir de sua própria camada de texto, que é exata e não custa nada. Um documento escaneado sem camada de texto recorre ao modelo de visão.
Quanto custa
Cada plano inclui uma cota mensal de imagens e minutos de voz (veja preços). O áudio é cobrado em minutos inteiros, arredondados para cima por clipe. Ler a camada de texto de um documento não usa cota alguma. O mesmo arquivo enviado duas vezes é processado apenas uma vez.
Tratamento e limites
- Metadados de localização e dispositivo são removidos das fotos antes de serem armazenadas.
- Dados pessoais são removidos do texto extraído antes de serem armazenados ou enviados a um modelo. Nomes não são removidos — isso exige reconhecimento de nomes que não executamos.
- Arquivos armazenados expiram na janela de retenção do seu plano, e o texto extraído expira junto.
- Texto encontrado dentro de uma imagem é tratado como dado, nunca como instrução ao bot.
- 25 MB por anexo. Gravações longas podem ser respondidas em uma mensagem de acompanhamento.
Hub MCPSomente no painel
O Hub MCP é o registro de Model Context Protocol do Rylvo — um catálogo selecionado de servidores MCP que seus bots podem usar como ferramentas. Gerencie em Painel → Hub MCP.
O que você pode fazer
- Descobrir e instalar servidores MCP
- Conectar servidores externos com transportes HTTP, SSE ou stdio
- Armazenar credenciais com segurança (criptografadas em repouso)
- Permitir servidores específicos por bot
- Ver logs de invocação e análises por servidor
- Enviar seu próprio servidor para revisão
Controles integrados
- Fluxo de aprovação antes que um servidor possa ser usado em produção
- OAuth 2.1 de saída (PKCE + DCR) para servidores voltados ao usuário
- Níveis de custo (baixo / médio / alto) exibidos antes da invocação
- Verificações de saúde e desativação automática em falhas repetidas
- Tokens de retomada para chamadas de ferramenta de longa duração
Build Intelligence: Você também pode expor todo o workspace do Rylvo como um servidor MCP para Claude Code, Cursor, Windsurf, Zed ou Codex. Veja a seção Build Intelligence abaixo ou visite /build-intelligence.
Build IntelligenceSomente no painel
O Build Intelligence permite que editores e agentes de IA controlem o Rylvo diretamente. Conecte Claude Code, Cursor, Windsurf, Zed ou Codex CLI via MCP e dê a eles mais de 160 ferramentas para criar bots, prompts, guardrails, habilidades, conexões de base de conhecimento, conectores, canais e muito mais. Gerencie a conexão em Painel → Build Intelligence ou visite /build-intelligence.
Clientes suportados
- Claude Code — comando de instalação HTTP remota + autorização /mcp
- Cursor — configuração de servidor remoto em mcp.json
- Windsurf — configuração de servidor remoto em mcp_config.json
- Zed — entrada de configuração context_servers
- Codex CLI — codex mcp add + codex mcp login
- Outros clientes Streamable HTTP — verifique o suporte a OAuth com o cliente
Modelo de segurança
- OAuth 2.1 com PKCE (S256) — fluxo de navegador na primeira instalação
- Tokens de acesso JWT RS256, TTL de 24 horas
- Tokens de atualização rotacionam a cada troca
- Cada chamada é limitada à organização: o org_id do token deve corresponder ao recurso
- Um token vazado pode agir apenas em sua organização vinculada até expirar ou ser revogado
Exemplos de instalação
# Claude Code
claude mcp add --transport http rylvo https://rylvo.com/mcp
# Then run /mcp inside Claude Code and authenticate
// Cursor — .cursor/mcp.json or ~/.cursor/mcp.json
{
"mcpServers": {
"rylvo": { "url": "https://rylvo.com/mcp" }
}
}
// Windsurf — ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"rylvo": { "serverUrl": "https://rylvo.com/mcp" }
}
}
// Zed — settings.json
{
"context_servers": {
"rylvo": { "url": "https://rylvo.com/mcp" }
}
}
# Codex CLI
codex mcp add rylvo --url https://rylvo.com/mcp
codex mcp login rylvo --scopes rylvo:read,rylvo:write
Superfície de ferramentas
| Recurso | Leitura | Gravação | Exclusão |
|---|---|---|---|
| Bots | bots.list, bots.get | bots.create, bots.update | bots.delete |
| Prompts | prompts.list, prompts.get | prompts.create, prompts.update, prompts.set_optimization | prompts.delete |
| Guardrails | guardrails.list, guardrails.get | guardrails.create, guardrails.update | guardrails.delete |
| Testes | tests.list_cases, tests.list_runs, tests.get_run_results | tests.create_case, tests.run_suite | tests.delete_case |
| Conectores | connectors.list, connectors.get | connectors.create, connectors.update, connectors.test | connectors.delete |
| Canais | channels.list, channels.get | channels.create, channels.update, channels.register_webhook | — |
| Servidores MCP | mcp_servers.list, mcp_servers.get | mcp_servers.register, mcp_servers.update | mcp_servers.delete |
| Habilidades | skills.list, skills.get | skills.create, skills.update | skills.delete |
| Base de Conhecimento | kb.list_connections, kb.get_connection | kb.create_connection, kb.update_connection, kb.add_source | kb.delete_connection |
| Grupos de Agentes | agent_groups.list | agent_groups.create, agent_groups.add_bot | agent_groups.delete |
| Automações | automations.list_tasks, broadcasts.list | automations.create_task, broadcasts.create | automations.delete_task, broadcasts.delete |
Ferramentas macro
scaffold_bot_from_description— criar um bot + prompt de sistema + guardrail inicial a partir de uma descriçãoclone_bot— duplicar um bot e opcionalmente copiar recursos vinculadosattach_mcp_server— registrar um servidor MCP externo, escrever suas ferramentas e vinculá-lo a bots Entitlements ainda se aplicam: o MCP não contorna acesso a produtos ou cotas. Cada ação de ferramenta é verificada em relação ao seu escopo, permissões do workspace, disponibilidade do plano, validação e os mesmos limites mostrados em Billing & Usage.
Workspace ArchitectSomente no Dashboard
O Architect é um agente de configuração conversacional que transforma um briefing em inglês simples em um workspace funcional: bots, prompts, guardrails, conectores, conexões de KB, regras de evolução e testes. Ele roda em /dashboard (aba Architect) e também alimenta o modo de edição em linguagem natural e a clonagem de bots.
Loop de agente em 8 fases
1. Intenção
Captura objetivo, setor, tom, restrições de conformidade
2. Pesquisa
Puxa padrões do perfil da organização, templates relevantes do setor, sessões anteriores
3. Blueprint
Propõe bots + fluxo de trabalho + guardrails + KB + conectores
4. Revisão
Usuário aprova / edita o blueprint em linguagem natural
5. Geração
Escreve prompts, guardrails, conectores, regras, stubs de KB
6. Verificação
Executa testes automáticos de bot nos novos bots e pontua a prontidão
7. Aplicação
Commita como recursos versionados, com tag source=architect
8. Handoff
Resume o que foi construído, com link para Mission Control e Playground
Outras capacidades do Architect
- Modo de edição - altera um bot existente com uma frase ("torne-o mais empático, prefira e-mail a telefone")
- Clonagem de bots - duplica um bot com modificações (setor, idioma, tom)
- Teste de bots - o architect pode executar testes e iterar até atingir um limite de prontidão
- Templates do setor - 29 pontos de partida (suporte SaaS, KYC fintech, triagem de saúde, etc.)
- Prefill do perfil da organização - reutiliza padrões definidos uma vez no perfil da sua organização
Knowledge BaseSomente no Dashboard
Conecte suas fontes de dados ao Rylvo para decisões fundamentadas e baseadas em evidências. A Knowledge Base oferece oito blueprints de recuperação disponíveis, de RAG Clássico e Busca Híbrida a Self-RAG, CRAG e RAG Agêntico.
Como funciona
1
Adicione uma fonte
Envie documentos, conecte APIs ou aponte para URLs. 16 tipos de fonte suportados.
2
Escolha um blueprint
Escolha entre oito estratégias de recuperação disponíveis, incluindo Busca Híbrida, HyDE e Self-RAG.
3
Crie uma conexão
Uma conexão vincula uma fonte a um blueprint com configurações específicas de pipeline.
4
Consulte no playground
Teste a qualidade da recuperação antes de entrar no ar. Ajuste chunking, reranking e limites.
Blueprints integrados
Recuperação de FAQConsulta de PolíticasGuia de Solução de ProblemasCatálogo de ProdutosJurídico / ConformidadeDocumentação de OnboardingReferência MédicaAvisos FinanceirosManual de RHManuais TécnicosPlaybook de VendasPipeline Personalizado
Recursos do Dashboard
Conexões
Crie, monitore, pause e exclua conexões da knowledge base
Fontes
Gerencie 16 tipos de fonte - upload, armazenamento em nuvem, SaaS, bancos de dados, API, rastreamento web
Blueprints
Configurações de pipeline de recuperação pré-construídas e personalizadas
Playground
Teste consultas, inspecione chunks recuperados, ajuste configurações ao vivo
Desempenho
Métricas de qualidade de recuperação, latência e taxas de acerto
Configurações
Auto-tune, configuração de chunking, reranking e ajuste de limites
Stack de recuperação
1
Armazenamento vetorial
O Qdrant armazena embeddings em chunks. Busca por palavra-chave e semântica são combinadas e depois reordenadas por relevância.
2
Descriptografia BYOK
Se uma fonte ou organização usa uma chave de provedor BYOK, ela é descriptografada no momento da recuperação antes de chamar o modelo de embedding.
3
Rastreamento de recuperação
Cada chamada de KB é registrada no armazenamento canônico de observabilidade como uma observação limpa de retriever por conexão, com latência, pontuação e estratégia.
4
Citações
Respostas fundamentadas incluem referências de fonte com IDs de chunk para que você possa auditar o que o bot realmente viu.
5
Classificação Self-RAG (opt-in)
O TypeSafe Jev classifica cada passagem recuperada como relevante ou não em uma única solicitação e descarta o restante; se rejeitar todas as passagens, todas são mantidas. Isso adiciona uma viagem de ida e volta na rede, mas não gasta mais seus tokens de modelo. Se o Jev não puder responder, o classificador LLM roda na sua chave OpenAI.
Conversation StorageSomente no Dashboard
Traga Seu Próprio Banco de Dados (BYODB). Cada evento de conversa que o Rylvo captura — cada mensagem, resposta coletada, checkpoint e resumo de sessão — é entregue a um banco de dados ou webhook que você possui, para que suas conversas vivam permanentemente na infraestrutura que você controla. Os eventos saem na execução de entrega a cada 15 minutos; sem conexão ainda, até 500 aguardam por uma. Gerencie em Dashboard → Conv. Storage.
Conexões
Adicione uma ou mais conexões. Cada uma recebe os eventos que você escolher, dos bots que você escolher.
- PostgreSQL, Supabase, Neon, PlanetScale
- MySQL, Turso, MongoDB, Redis
- Webhook (nenhum / chave de API / Bearer / autenticação HMAC)
- Credenciais criptografadas em repouso; verifique uma conexão salva a qualquer momento
Tabelas e colunas
Cada bot grava com um template — suas tabelas e a coluna em que cada valor entra.
- Nove templates, ou colunas próprias da conexão e campos personalizados
- Veja exatamente quais colunas cada evento grava
- Crie as tabelas com um clique ou copie o SQL — o Rylvo nunca altera uma tabela
Salvamentos ao vivo, histórico de entrega, eventos com falha
Cada evento de conversa, um a um, e cada entrega com seu resultado.
- Por que algo ainda está aguardando, por evento
- Novas tentativas de webhook dentro de uma execução (0,5 s → 1 s → 2 s) e depois a próxima execução
- Inspecione o payload exato que foi enviado
- Após 10 execuções com falha, os eventos vão para Eventos com falha — reproduza ou descarte-os
- Teste e Produção são separados — siga o alternador de ambiente
Retenção
Por quanto tempo o Rylvo mantém seu histórico de entrega (cada registro carrega o conteúdo do evento). Estenda com um add-on de retenção ou reduza.
Lite14 dias
Pro90 dias
EnterpriseIlimitado
Isolamento Produção / Teste
Cada evento de armazenamento carrega um discriminador source:channel (ao vivo), playground (chat do dashboard) ou test_suite (avaliação automatizada). Tráfego ao vivo vai para Produção e chats do dashboard para Teste — cada um com suas próprias conexões, fila e histórico. Cada página de Conversation Storage segue o alternador de ambiente.
Ao vivo (canal)
- Tráfego de canais implantados: Telegram, WhatsApp, widget, API, etc.
- Grava em tabelas base (ex.:
rylvo_conversations) - Usa a chave de circuit-breaker de produção
- Contabilizado nos eventos de armazenamento do seu plano
Teste (playground)
- Turnos de Bot Chat / Group Chat do Dashboard
- Grava em tabelas com sufixo (padrão
*_test) - Sufixo configurável por destino ou
testDatabaseNameopcional - Chave de circuit-breaker separada — tabelas de teste ausentes nunca afetam a entrega ao vivo
- Payloads de webhook incluem
sourceeisTest - Entregue somente quando Allow verified Test deliveries estiver ativado (Settings → Organization) — caso contrário, retido, sem cobrança
Crie as tabelas primeiro. O Rylvo apenas insere linhas; ele nunca cria tabelas por conta própria. A aba Tables de cada conexão de banco de dados tem as instruções exatas — para Produção e, em Teste, as tabelas *_test correspondentes — e as executa com as credenciais salvas.
Seu banco de dados é a fonte da verdade. A cópia do Rylvo é um cache operacional — não um backup. Adicione uma conexão para manter suas conversas permanentemente no seu próprio banco de dados. Estender a retenção do lado do Rylvo aumenta os custos de armazenamento, mas não substitui seu próprio banco de dados.
Audience HubSomente no Dashboard
O workspace operacional central para gerenciar cada usuário final em cada bot da sua organização. Substitua listas de usuários dispersas por um hub escalável: navegação paginada de pessoas, segmentos de filtro salvos, análises agregadas, governança de consentimento, importação/exportação CSV e controles de política de retenção. Gerencie em Dashboard → Audience.
Pessoas
Lista paginada e orientada por servidor de usuários finais com páginas de cursor de 50 linhas por padrão e máximo de 200.
- Filtre por canal, escopo de consentimento, status de esquecimento ou busca por texto livre
- Filtragem com escopo de bot com predicados de campo de coleta de dados
- Página completa de pessoa com abas Overview, Sessions, Profiles, Activity e Audit
- Ações em massa de tags, consentimento, sessões, remoção, exportação, mesclagem e broadcast elegível
- Capturas anônimas de widget e identidades de teste permanecem separadas das Pessoas de produção
- Atalhos de teclado:
/busca,j/knavegação,Enterinspeção
Audience Rooms
Presets de filtro salvos que funcionam como visualizações persistentes. Crie rooms para coortes comuns e compartilhe com sua equipe.
- Salve qualquer combinação de filtro como um room nomeado
- Indicador de alteração quando os filtros atuais divergem
- Pins e painel de Discussão por room
- Link direto via parâmetro de URL
?room=
Segmentos
Filtros reutilizáveis que se resolvem em listas concretas de membros para broadcasts e exportações.
- Predicados básicos: todos os usuários, ativos nos últimos N dias, por canal, mínimo de conversas
- Predicados de perfil: checkpoint alcançado, valor de campo, limite de completude
- Pré-visualização ao vivo com contagem de correspondências antes de salvar
- Link com um clique para a aba de broadcast do bot
Insights
Análises agregadas em cache calculadas a partir de um snapshot (TTL de 6h). No nível da organização ou com escopo de bot.
- Funil de onboarding, mix de canais, detalhamento de consentimento
- Profundidade de engajamento, recência de atividade, heatmap por hora do dia
- Taxas de preenchimento de campos, principais tags, histograma de completude
- Leaderboard de bots (somente no nível da organização)
Importações e Exportações
Traga contatos legados de CRM e exporte segmentos para seu data warehouse.
- Assistente de importação CSV: upload → mapear colunas → pré-visualizar → confirmar (idempotente)
- Exportação de segmento para CSV (até 5.000 linhas)
- Limite de arquivo de 15 MB mais um limite de linhas específico do plano
Consentimento e Privacidade
Governa como os dados do usuário final são coletados e retidos.
- Tiles de escopo de consentimento: none, short_term_only, personalize, full
- Fila de usuários esquecidos do GDPR com deep-links
- Política de retenção: dias efetivos, substituição de redução, add-ons de extensão
- A varredura de retenção agendada remove registros expirados
Profiles & Schema
Catálogo de campos no nível da organização + cards de schema por bot. Detecte desvios de nomenclatura antes que eles estraguem dashboards.
Settings
Política de retenção, níveis de add-on e governança. Configuração somente para administradores.
People DatasetsSomente no Dashboard
Coleções nomeadas de usuários finais (não traces). Armazenadas na mesma coleção de datasets que os trace datasets, discriminadas por kind === "people". Criadas a partir de pins de Audience Room ou diretamente da página People. Sem mecanismo de retenção/bloqueio de exportação (diferente dos trace datasets). Cotas aplicadas via limite maxDatasets do plano. Gerencie em Dashboard → Datasets → People.
Documento de dataset
name(1-200 caracteres),description(máx. 2000)kind: "people" (discriminador; documentos legados sem kind = "trace")peopleCount: contagem desnormalizada de usuários finaisretentionPolicy: { mode: "inherit" } (não aplicado para people)archived: flag de exclusão suave
Documento de item
externalId(1-500 caracteres, identificador do usuário final)source: "audience_room" | "people_page"addedBy,addedByName,addedAtsnapshot: channel, displayName, consentScope, turnCount, lastSeenAtMs, firstSeenAtMs- ID do documento = externalId → adicionar/remover é idempotente
Discriminador de tipo: people vs trace
- people: agrupa perfis EndUserDoc, sem aplicação de retenção, sem bloqueio de exportação
- trace: agrupa traces TraceView, retenção ativa, bloqueio de exportação
- Ambos na mesma coleção Firestore (
datasets) - Filtragem:
.filter(r => r.data.kind === "people")
3 fluxos de criação
- A partir de pins de Audience Room:
createPeopleDatasetFromRoomPins()— busca todos os pins, source="audience_room" - A partir da página People Datasets: cria dataset vazio, adiciona pessoas individualmente
- A partir da página People:
addPeopleToDataset()adição em massa, source="people_page"
Aplicação de cota (maxDatasets)
- Free: 1 | Starter: 1 | Lite: 10 | Pro: 50 | Enterprise: ilimitado (-1)
- Verificação de contagem transacional (segura contra corrida dentro da transação Firestore)
- Datasets arquivados excluídos da contagem; apenas kind="people" é contado
- Erro:
PlanAccessErrorcode="quota_exceeded", status 429
RBAC
- Ler: qualquer membro da organização (viewer+)
- Criar: operador+ (deve definir createdBy = auth.uid, nome obrigatório)
- Atualizar: operador+ | Arquivar: operador+
- Excluir: admin+ (exclusão definitiva + todos os itens em blocos de 500)
- Itens: leitura = membro; criação = operador+; exclusão = operador+
Operações idempotentes
- Adicionar item: retorna
{ added: false }se já existir - Remover item: retorna
{ removed: false }se não existir - peopleCount incrementado/decrementado atomicamente
- Não é possível adicionar pessoas a um conjunto de dados arquivado
Relacionamentos e auditoria
- Audience Rooms: pins → itens do conjunto de dados via createPeopleDatasetFromRoomPins()
- Broadcasts: NÃO são usados atualmente como alvos de broadcast (futuro: tipo de alvo "dataset")
- Auditoria: people_dataset.created / updated / archived / deleted / item_added / item_removed
- Tipo de recurso: "people_dataset"
Endpoints da API (Python FastAPI)
- POST /v1/people-datasets/{company_id} — criar conjunto de dados (201, verificação de cota)
- PUT /v1/people-datasets/{company_id}/{dataset_id} — atualizar nome/descrição
- POST /v1/people-datasets/{company_id}/{dataset_id}/archive — arquivar (exclusão lógica)
- DELETE /v1/people-datasets/{company_id}/{dataset_id} — exclusão definitiva + todos os itens
- POST /v1/people-datasets/{company_id}/{dataset_id}/items — adicionar pessoa (idempotente)
- POST /v1/people-datasets/{company_id}/{dataset_id}/items/{external_id}/remove — remover pessoa
Todos exigem authorize_org. Adicionar item: external_id (1-500), source?, added_by, added_by_name, snapshot?.
Estrutura do Firestore
{envRoot}/datasets/{datasetId}
|- name (1-200), description (max 2000)
|- kind: 'people' (discriminator)
|- createdBy, createdByName
|- peopleCount: number (denormalized)
|- traceCount: 0 (not used for people)
|- retentionPolicy: { mode: 'inherit' } (not enforced)
|- tags: [], archived: boolean
+- createdAt, updatedAt: Timestamp
{envRoot}/datasets/{datasetId}/items/{externalId}
|- externalId (1-500), source: audience_room | people_page
|- addedBy, addedByName, addedAt
+- snapshot: { externalId, channel, displayName?,
consentScope, turnCount, lastSeenAtMs?, firstSeenAtMs? }
Quota: maxDatasets (Free: 1 | Starter: 1 | Lite: 10 | Pro: 50 | Enterprise: -1)
Count excludes archived; only kind='people' counted
BroadcastsSomente painel
Mensageria multicanal de saída — envie a mesma campanha para templates do WhatsApp, SMS, e-mail e no aplicativo a partir de um único compositor. Uploads de audiência (CSV / XLSX / colar), limites de taxa derivados da plataforma, rastreamento de entrega por destinatário e histórico com nível de auditoria são integrados. Gerencie em Painel → Broadcasts.
Compositor em 5 etapas
Audiência → Canais → Conteúdo → Agendamento → Revisão. As regras da plataforma são exibidas no momento da seleção da audiência, nunca no momento da entrega.
- 4 fontes de audiência: segmento salvo, upload, colar, todos os contatos anteriores
- Canais alternáveis com anotação de regras por canal
- Template + enriquecimento por LLM + variáveis por linha
- Único, recorrente (de hora em hora → mensal) ou "Enviar agora"
12 canais de broadcast
E-mail, no aplicativo, WhatsApp, SMS (Twilio), WhatsApp (Twilio), Telegram, LINE, Slack, Discord, MS Teams, Messenger, Instagram, Web Widget. Cada um anotado com veredito de envio a frio e limite da plataforma.
- WhatsApp: seletor de templates aprovados sincronizado com o Meta Graph
- WhatsApp (Twilio): usa o Twilio Programmable Messaging com prefixo E.164
whatsapp: - SMS: com aceitação obrigatória, Twilio REST direto da rota de despacho
- LINE: resposta/push via LINE Messaging API; secret do canal + token de acesso criptografados em repouso
- Telegram / Web Widget / Discord: envio a frio bloqueado com explicação
Uploads de audiência
CSV / XLSX analisados no servidor (SheetJS) e lista colada com classificador e deduplicação. Até 50 mil linhas por upload; colunas de variáveis por linha são mescladas ao template no momento do envio.
- Detecção automática do tipo de identificador: telefone, e-mail, ID do canal
- Avisos exibidos antes do commit
- Espelhamento opcional "salvar na audiência" em endUsers
Rastreamento de entrega
Cada destinatário grava uma linha botBroadcastDeliveries: na fila / enviado / falhou / ignorado, além de IDs de mensagem do provedor quando disponíveis.
- Documento por execução com contagens enviado / falhou / ignorado por canal
- Gaveta de histórico agrupa entregas por canal + status
- Log de auditoria: broadcast.created / scheduled / deleted
Limites de taxa e segurança
Limitador de taxa por token bucket por canal no runner cron. Os limites espelham os tetos documentados da plataforma para que uma execução intensa não suspenda a conta subjacente.
- WhatsApp: 4.800/min (~80/s/número, padrão Meta)
- SMS: 60/min (conservador Twilio)
- Operadores podem reduzir por broadcast, nunca aumentar acima do limite da plataforma
Capacidades e RBAC
Quatro chaves de capacidade controlam o recurso, espelhando o restante do painel.
broadcasts.view— viewer+broadcasts.create— operador+broadcasts.send— admin+broadcasts.delete— admin+
Endpoints da API
- POST /api/bots/broadcasts/dispatch — despacho por destinatário × por canal (cron + token de ID)
- POST /api/bots/broadcasts/generate-content — enriquecimento por LLM (cron + token de ID)
- POST /api/broadcasts/upload — analisador de CSV / XLSX / lista colada
- POST /api/broadcasts/recipients/save-to-audience — espelhamento idempotente em endUsers
- GET /api/channels/whatsapp/templates?orgId=…&botId=… — catálogo de templates aprovados pela Meta
Estrutura do Firestore
{envRoot}/botBroadcasts/{broadcastId}
|- targets.type: "all" | "selected" | "segment" | "uploaded"
|- targets.uploaded.rows: UploadedRecipient[]
|- delivery.channels: BroadcastChannel[]
|- delivery.whatsappTemplate: WhatsAppTemplateRef | null
|- delivery.rateLimitPerMinute: number | null
+- deliveries/{deliveryId}
|- runId, channel, identifier, identifierKind
|- status: "queued" | "sent" | "failed" | "skipped"
|- providerMessageId, error
+- attemptedAt, deliveredAt
{envRoot}/botBroadcastRuns/{runId}
|- status: "success" | "partial" | "failed"
|- perChannelStats: { [channel]: { sent, failed, skipped } }
|- targetCount, sentCount, failedCount, skippedCount
+- generatedContent, errors[]
Equipe e RBACSomente painel
Controle de acesso baseado em funções para cada superfície do painel. Quatro funções hierárquicas, convites por e-mail, solicitações de entrada, concessões granulares de acesso a páginas e transferência de propriedade. SSO / SAML e provisionamento SCIM estão disponíveis no Enterprise. Gerencie em Painel → Equipe.
Hierarquia de funções (hierárquica)
Quatro funções com aplicação estrita baseada em hierarquia. Nenhuma ação pode ter como alvo um membro no mesmo nível ou acima do seu.
- Proprietário (nível 3) — acesso total, cobrança, transferência de propriedade
- Admin (nível 2) — gerenciar bots, chaves, equipe, aprovações, ver log de auditoria
- Operador (nível 1) — executar bots, testes, intervenções, aprovar solicitações
- Visualizador (nível 0) — acesso somente leitura ao painel
Matriz de capacidades (selecionada)
team.view— viewer+team.invite— admin+team.remove_member— admin+team.change_role— admin+team.transfer_ownership— proprietárioaudit.view— admin+audit.export— admin+ (+ plano Pro)org.manage_sso— proprietário (+ Enterprise)
Convites (por e-mail)
Admin+ convida por e-mail. O limite do plano é aplicado no momento do convite e da aceitação, contando os assentos em uso: delegados de agência trabalham nos assentos da agência e não são contados contra o limite do cliente. ID de convite determinístico a partir do hash SHA256. Limite de taxa: 10 convites/min.
- Expiração padrão: 7 dias. Status: pendente / aceito / expirado / cancelado
- Gravação atômica: convite + log de auditoria + contador de uso da organização em uma transação
- Aceitação: o e-mail deve corresponder, o limite do plano é verificado novamente, documento de membro criado
- Reenviar / cancelar são ações de admin+, ambas registradas em auditoria
Solicitações de entrada (entre organizações)
Não membros podem solicitar entrada com um perfil (função, tipo de trabalho, interesses, caso de uso). Admins aprovam ou negam com motivo opcional.
- Perfil captura: fundador / engenheiro / gerente de produto / designer / operações / analista / outro
- Tipo de trabalho: construir agentes, integrar API, gerenciar fluxos de trabalho, analisar dados, explorar
- Ações de auditoria: page_access.approved / page_access.denied
Concessões de acesso a páginas
Elevação granular para duas páginas restritas: audit_log e billing. Não admins veem um botão "Solicitar acesso".
- A solicitação envia notificação no aplicativo para todos os admins
- Aprovar → pageId adicionado ao array pageAccessGrants do membro
- Negar → resolverNote opcional. Revogar remove a concessão
- Acesso: a função concede capacidade OU pageAccessGrant explícito
Mudança e remoção de função
Não é possível mudar a própria função, não é possível agir em membros do mesmo nível ou superior, não é possível atribuir acima do próprio nível. A remoção é apenas exclusão lógica.
- Rebaixamento enfileira evento durável de outbox para efeitos colaterais (revogação de chave de API)
- Remoção: status → "desativado", revoga todas as chaves de API via outbox
- Transferência de propriedade: troca atômica, duas entradas de auditoria, org.ownerId atualizado
- SSO/SAML: disponível no Enterprise; propriedade de domínio aplicada, break-glass obrigatório, aplicação no servidor
- SCIM 2.0: provisionamento e desprovisionamento de usuários; gravações de função recusadas, desprovisionamento é exclusão lógica
Endpoints da API
- POST /api/team/invite — criar convite por e-mail (admin+)
- POST /api/team/invite/accept — aceitar convite (qualquer usuário autenticado)
- POST /api/team/members/{uid}/role — mudar função do membro (admin+)
- POST /api/team/transfer-ownership — transferir propriedade da organização (somente proprietário)
Estrutura do Firestore
organizations/{orgId}/members/{uid}
|- uid, email, displayName
|- role: owner / admin / operator / viewer
|- status: active / deactivated
|- pageAccessGrants?: ("audit_log" | "billing")[]
|- joinedAt, deactivatedAt?, deactivatedBy?
+- createdAt, updatedAt
organizations/{orgId}/invitations/{inviteId}
|- email, role, status, invitedBy, inviterName
|- expiresAt, acceptedAt?, emailStatus?
organizations/{orgId}/joinRequests/{requestId}
|- userId, userEmail, orgId, status, profile, requestedRole?
|- requestedAt, resolvedAt?, resolvedBy?, denialReason?
organizations/{orgId}/pageAccessRequests/{requestId}
|- pageId, requesterId, requesterEmail, status
|- requestedAt, resolvedAt?, resolvedBy?, resolverNote?
Espaços de Trabalho de Agência e ClienteSomente painel
Agências podem operar muitos espaços de trabalho de clientes sem transformar o espaço da agência em um único tenant compartilhado. Cada cliente mantém seu próprio proprietário, equipe, recursos, cobrança, histórico de auditoria e ambientes de Teste/Produção. A parceria concede acesso aprovado; ela não move os dados do cliente. Gerencie em Painel → Clientes e Parceiros.
Disponível no Pro e Enterprise
Tanto o espaço de trabalho da agência quanto o do cliente precisam do Pro ou Enterprise antes que o acesso gerenciado possa ser ativado. Uma agência no Free, Starter ou Lite não pode enviar uma solicitação. Um cliente nesses planos ainda pode inspecionar e recusar uma, mas deve fazer upgrade antes de aprovar. Visualizar, recusar, encerrar e revogar permanecem disponíveis em todos os planos.
Agência Free / Starter / Lite
Visualizar e fechar registros; não pode enviar solicitações.
Cliente Free / Starter / Lite
Visualizar e recusar; não pode aprovar.
Pro / Enterprise em ambos
Fluxo completo de solicitação, aprovação, delegação, alternância e revogação.
Por que Teste e Produção mostram a mesma página
A relação agência–cliente pertence ao espaço de trabalho inteiro, então /dashboard/test/clients e /dashboard/production/clients resolvem intencionalmente para uma única tela canônica de Clientes e Parceiros. Isso não combina os ambientes do cliente. Depois que um delegado abre o espaço de trabalho do cliente, o seletor de ambiente ainda determina se ele está trabalhando com recursos e dados de runtime de Teste ou Produção.
1. O cliente compartilha o ID do espaço de trabalho
- O cliente permanece uma organização Rylvo completamente separada
- O ID do espaço de trabalho identifica o destino; ele não concede acesso por si só
- O proprietário do cliente, membros diretos, recursos e dados não se movem
2. A agência solicita acesso exato
- Um admin da agência seleciona os colegas exatos para delegar
- Cada delegado recebe acesso de admin, operador ou visualizador
- A solicitação pode incluir uma nota e relação comercial
3. O proprietário do cliente aprova
- Nada é concedido enquanto a solicitação está pendente
- Somente o proprietário do cliente pode aprovar ou recusar
- A aprovação reverifica ambos os planos, delegados e colisões com membros diretos; não precisa de assento gratuito do cliente
4. Delegados trabalham dentro do cliente
- Abrir cliente usa o alternador normal de espaço de trabalho e recarga forçada
- RBAC normal do cliente, limites de plano e limites de ambiente ainda se aplicam
- Cada associação delegada registra sua agência e proveniência de relacionamento
Governança permanece com o cliente
- Admins delegados podem construir e implantar, mas não podem governar o espaço de trabalho do cliente
- Equipe do cliente, propriedade, configurações da organização, cobrança e parcerias são bloqueadas
- Associações diretas existentes do cliente nunca são rebaixadas ou reclassificadas
Cobrança e revogação segura
- O cliente possui sua assinatura, carteira, transações, uso e direitos
- O modo comercial registra o acordo de negócios; ele não enfraquece o isolamento
- Encerrar a parceria remove acesso delegado e chaves sem excluir dados do cliente
- Rebaixamentos voluntários abaixo do Pro são bloqueados até que relacionamentos ativos sejam encerrados
- Perda forçada de direitos encerra automaticamente o link e preserva todos os dados de propriedade do cliente
Ciclo de vida do relacionamento
pending_client_approval → active → ended
↘ declined
declined / ended → pending_client_approval (new request revision)
Pro/Enterprise entitlement lost → ended + delegated access revoked
Rotas da API do painel
- GET /api/agency/portfolio?orgId=… — resumos de relacionamento (admin+ da organização atual)
- POST /api/agency/relationships — solicitar acesso (admin+ da agência e Pro/Enterprise)
- POST /api/agency/relationships/{id}/respond — aprovar (proprietário do cliente e Pro/Enterprise) ou recusar (proprietário do cliente em qualquer plano)
- DELETE /api/agency/relationships/{id} — encerrar e revogar (admin+ da agência ou proprietário do cliente)
Estrutura do plano de controle
agencyClientRelationships/{sha256(agencyOrgId:clientOrgId)}
|- agencyOrgId, clientOrgId, relationshipId, revision
|- status, delegates[], commercialModel, requestMessage?
|- requestedBy/At, approvedBy/At?, declinedBy/At?, endedBy/At?
+- server-owned: no direct browser reads or writes
organizations/{clientOrgId}/members/{delegateUid}
|- membershipKind: "agency_delegate"
|- agencyOrgId, agencyRelationshipId
|- role: admin | operator | viewer
+- delegatedAt, delegatedBy
Log de AuditoriaSomente painel
Trilha de auditoria imutável e à prova de adulteração para cada ação material na plataforma. Mais de 200 tipos de ação, gravação de outbox em dois estágios com assinaturas de integridade HMAC-SHA256, paginação por cursor e exportação CSV. Gerencie em Painel → Log de Auditoria.
Padrão de gravação em dois estágios
Cada mutação prepara um evento de auditoria no outbox na mesma transação do Firestore — a atomicidade é garantida. Uma Cloud Function drena o outbox para o log de auditoria canônico e somente leitura.
- Estágio 1: auditOutbox (transacional, mesmo lote da mutação)
- Estágio 2: auditLog (durável, somente leitura, drenado por worker)
- Assinatura de integridade HMAC-SHA256 em todo documento do outbox
- Tanto a web (Admin SDK) quanto a API Python gravam pelo mesmo pipeline
Catálogo de ações (200+)
Cobre toda ação material: equipe, chaves de API, org, bots, workflows, prompts, testes, casos extremos, guardrails, KB, traces, mission control, evolução, automação, MCP Hub, skills, audiência, transmissões, conectores, autenticação e sessões de configuração.
- 40+ tipos de recursos (membro, bot, prompt, guardrail, trace, transmissão…)
- Cada entrada: ator, ação, resourceType, resourceId, detalhes, IP, UA, origem
- Discriminador de origem: web / api / mcp / system
Filtragem e busca
Filtre por ação, resourceType, resourceId, origem, intervalo de datas, e-mail do ator e nome do ator. Busca de texto completo em todos os campos, incluindo o JSON de detalhes.
- Paginação baseada em cursor (cursor opaco: timestamp + docId)
- Padrão de 25/página, máximo de 500/requisição
- Limite de taxa: 120 req/min por IP no endpoint BFF
Exportação e conformidade
Exportação CSV com todos os campos. Restrita por capacidade e plano.
- Colunas: id, timestamp, actorName, actorEmail, actorId, action, resourceType, resourceId, details
- Exige
audit.export(admin+) E plano Pro+ - Os logs de auditoria são imutáveis após a canonicalização
- Retenção segue a política específica da org; purga GDPR via endpoints de observabilidade
RBAC
Visualização e exportação são restritas separadamente. Não-admins podem solicitar acesso pelo sistema de concessão de acesso à página.
audit.view— admin+ OU pageAccessGrants: ["audit_log"]audit.export— admin+ E plano Pro+- Não-admins veem "Solicitar Acesso" na página de log de auditoria
Integridade e segurança
A assinatura HMAC-SHA256 em todo documento do outbox impede adulteração. As regras do Firestore bloqueiam gravações diretas no auditLog.
- Campos assinados: idempotencyKey, action, resourceType, resourceId, actor, details, source
- JSON canônico com chaves ordenadas
- Sem gravações diretas de clientes no auditLog — tudo passa pelo staging do outbox
- O leitor lida tanto com objetos de ator aninhados quanto com campos legados planos
Endpoint de API (BFF)
- GET /api/audit?orgId=…&action=…&resourceType=…&startDate=…&endDate=…&q=…&actorEmail=…&actorName=…&cursor=…&limit=… — lista entradas de auditoria
Autenticação: token de ID do Firebase (Bearer). Resposta: { orgId, total, records[], nextCursor }. Cache-Control: private, max-age=5, stale-while-revalidate=30.
Estrutura do Firestore
organizations/{orgId}/auditOutbox/{docId} (transient staging)
|- idempotencyKey, action, resourceType, resourceId
|- actor: { uid, email, displayName }
|- details: { schemaVersion, ...custom }
|- ipAddress, userAgent, source
|- processed: boolean, processedAt, error, retryCount
|- stagedAt, stagedBy, integrity (HMAC-SHA256)
organizations/{orgId}/auditLog/{docId} (canonical, read-only)
|- idempotencyKey, action, resourceType, resourceId
|- actor: { uid, email, displayName }
|- details: { schemaVersion, ...custom }
|- ipAddress, userAgent, source
+- timestamp: Timestamp
Indexes required:
auditOutbox: (processed, stagedAt)
auditLog: (action, timestamp desc), (resourceType, timestamp desc),
(source, timestamp desc), (timestamp desc, __name__ desc)
API KeysSomente dashboard
Geração, gerenciamento e revogação de chaves de API em nível de org, com escopo de ambiente, escopos de permissão, substituições de limite de taxa e hash SHA-256. As chaves autenticam requisições de API externas (bot-run, consulta de KB, documentos de KB). Gerencie em Dashboard → API Keys.
Documento de chave de API
name— rótulo legível por humanoskeyPrefix— primeiros 12 caracteres para exibiçãokeyHash— SHA-256 da chave bruta (nunca armazene a chave bruta)environment— production | test (staging/development legados mapeiam para test)permissions— array de escopos de APIrateLimitOverride— chamadas/min (null = padrão 60)botId— vínculo opcional de bot
Geração de chave e hash
- Formato:
rylv_{40 hex chars}(46 caracteres) - Entropia: 20 bytes = 160 bits (
crypto.getRandomValues) - Hash: SHA-256 via Web Crypto API
- Apenas o hash é persistido; a chave bruta é mostrada uma vez na criação
- Prefixo (primeiros 12 caracteres) armazenado para identificação na exibição
Escopos de permissão (5 + 2 curingas)
respond— POST /api/v1/bot-run + widget-pollkb:read— POST /api/v1/kb/querykb:write— POST /api/v1/kb/documentstests:read— POST /api/v1/tests/gatetrace.read— reservado para uso futuro*— acesso total |kb:*— todo o KB- A normalização descarta escopos não reconhecidos; padrão é ["respond"]
Fluxo de autenticação
- Cabeçalhos:
Authorization: Bearer|X-API-Key|X-Rylvo-Key - Hash SHA-256 da chave bruta, consulta por grupo de coleção usando keyHash
- Verifique status == "active", extraia orgId do caminho
- Atualização assíncrona de lastUsedAt (não fatal se falhar)
- Retorna AuthIdentity com permissões + rateLimitOverride
Operações CRUD
- create: gerar + hash + normalizar, gravação em lote (doc + contador + auditoria)
- list: filtrar por status, ordenado por createdAt desc
- update: nome, ambiente, permissões, botId + auditoria
- revoke: status → "revoked", decrementar contador + auditoria
- revokeAllForMember: revogação em massa na remoção de membro
- hardDelete: exclusão física (rollback de provisionamento)
Limite de taxa
- Padrão: 60 chamadas/minuto por chave
- Substituição via campo
rateLimitOverride - Token bucket via
consumeTokenUnified() - Resposta 429 com cabeçalho
Retry-After - Buckets por rota (bot-run, kb/query, etc.)
RBAC e limites de plano
apiKeys.view— admin+apiKeys.create— admin+apiKeys.revoke— admin+- Free: 0 | Starter: 0 | Lite: 10 | Pro: 25 | Enterprise: ilimitado
- Uma chave que um workspace Free já possui continua funcionando; apenas criar uma nova é recusado
- Cota aplicada nas regras do Firestore (
withinApiKeyQuota) - Não-admins veem RestrictedPlaceholder
Auditoria e limpeza
- Eventos: api_key.created / updated / revoked (com ator, IP, UA)
- Revogação em massa registra { count, memberUid }
- Exclusão de bot: exclui fisicamente chaves vinculadas, decrementa apenas o contador ativo
- Workspace Architect: cria automaticamente chave com permissões padrão, rollback via hardDelete
- Rota de migração: backfill normalizeApiKeyPermissions (idempotente)
Endpoints de API (BFF)
- POST /api/v1/bot-run — executa turno de bot (permissão: respond, replay de idempotência)
- POST /api/v1/kb/query — consulta KB (permissão: kb:read)
- POST /api/v1/kb/documents — envia documentos (permissão: kb:write, máx. 100)
- POST /api/v1/tests/gate — gate de release para CI (permissão: tests:read)
Autenticação: chave de API via cabeçalho Bearer / X-API-Key / X-Rylvo-Key. Limite de taxa por chave.
Estrutura do Firestore
{envRoot}/apiKeys/{keyId}
|- name, keyPrefix (12 chars), keyHash (SHA-256)
|- environment: production | test (legacy: staging, development map to test)
|- permissions: string[] (respond, kb:read, kb:write, trace.read, *, kb:*)
|- status: active | revoked
|- rateLimitOverride: number | null (calls/min)
|- botId?, botName?
|- createdBy, createdAt
|- lastUsedAt?, revokedAt?, revokedBy?
Quota: usage.apiKeyCount vs settings.maxApiKeys
Free: 0 | Starter: 0 | Lite: 10 | Pro: 25 | Enterprise: -1 (unlimited)
ApprovalsSomente dashboard
Workflow de aprovação com humano no loop para execução de ferramentas. Dois sistemas: aprovações de ferramentas de conector (nível de API, para ferramentas de webhook/conector com flag requires_approval) e aprovações de ferramentas MCP (MCP Hub, para ferramentas com permissão require_approval). O Mission Control adiciona timeouts baseados em urgência e pontuação de risco. Máquina de estados: pending → approved / denied / expired.
Aprovação de ferramenta de conector
- Acionada quando a ferramenta tem
safety_restrictions.requires_approval = True - Formato
approval_id:aprv_{tool_call_id} - TTL padrão: 24 horas (86400s)
- Fire-and-forget: a ferramenta retorna falha com approval_id imediatamente
- Bot/frontend consulta o status separadamente; sem re-invocação automática após aprovação
Aprovação de ferramenta MCP
- Níveis de permissão:
allow|require_approval|deny - Padrões baseados em risco: baixo/médio → allow, alto/crítico → require_approval
- TTL padrão: 10 minutos (600.000 ms)
- argsPreview (JSON com dados removidos, máx. ~2KB) + llmRationale opcional
- Assinaturas em tempo real do Firestore para aprovações pendentes
Máquina de estados
- pending → approved (via service.approve)
- pending → denied (via service.deny com motivo)
- pending → expired (expiração automática quando o TTL passa)
- Apenas pending → approved/denied é permitido (idempotente)
- Aprovar/negar duas vezes retorna None (já resolvido)
- Mission Control adiciona: status
auto_denied
Níveis de urgência do Mission Control
- immediate — timeout de 15s, informativo de baixo risco
- standard — timeout de 120s, acesso a dados / relacionado a PII
- extended — timeout de 900s, financeiro / jurídico / conformidade
- Expiração calculada no servidor (createdAt + timeoutSeconds)
- Inclui riskScoreAtTime + riskSignals[] + conversationContext
Métodos do ApprovalService
request_approval()— cria pending, persiste, registra eventoapprove()— verifica pending, atualiza, registra, idempotentedeny()— verifica pending, atualiza + motivo, registra, idempotentelist_pending()— consulta + filtra expirados + registra obsoletos
Expiração e cloud functions
- cleanupExpiredMcpApprovals — a cada 5 min, aprovações MCP após TTL
- missionControlExpireApprovals — a cada 2 min, aprovações MC após timeout
- Ambos gravam entradas de auditoria para expiração iniciada pelo sistema
- Polling do frontend: backoff exponencial de 1-30s, timeout local de 5 min
RBAC
- Aprovações de conector: leitura = admin+; gravação = somente servidor (regras: false)
- Aprovações MC: leitura = membro; criação/atualização = operator+; exclusão = admin+
- Aprovações MCP: leitura = membro; criação/atualização = operator+; exclusão = admin+
- Capacidade
resolve_approval: operator+ (Mission Control) - Página de Aprovações do MCP Hub: admin+ para botões de aprovar/negar
Auditoria e analytics
- Expiração MC grava auditoria: eventType "approval_resolved", ator "system_sweep"
- Analytics: MCApprovalResolvedEvent { request_id, bot_id, action_type, resolution, response_time_ms, urgency }
- Log de auditoria: approval.requested / approved / denied / expired / resolved
- Chave de idempotência em aprovações MC para semântica de exatamente uma vez
Endpoints de API (Python FastAPI — aprovações de conector)
- POST /v1/approvals/{approval_id}/approve — aprova (query: approver_email?)
- POST /v1/approvals/{approval_id}/deny — nega (query: reason?, approver_email?)
- GET /v1/approvals/pending?company_id=…&bot_id=…&session_id=… — lista pendentes
GET pending exige authorize_org. 404 se não encontrado ou já resolvido. Aprovações MCP gerenciadas via dashboard em /dashboard/mcp-hub/approvals.
Estrutura do Firestore
{envRoot}/approvalRequests/{approvalId} (connector + Mission Control)
|- approval_id (aprv_{tool_call_id}), tool_call_id, tool_name
|- arguments: dict, status: pending | approved | denied | expired
|- company_id, org_id, bot_id?, session_id, workflow_id?
|- requested_at, expires_at (24h default)
|- resolved_at?, resolved_by?, denial_reason?
|- trace_id, request_id
|- (MC) urgency, timeoutSeconds, riskScoreAtTime, riskSignals[]
|- (MC) conversationContext, idempotencyKey?
+- created_at: Timestamp
{envRoot}/mcpApprovalRequests/{requestId} (MCP Hub)
|- requestId, serverId, serverName, toolId, toolName, toolDisplayName
|- botId, botName, conversationId?, requestedBy, requestedByDisplay?
|- argsPreview (redacted, ~2KB), llmRationale?
|- status: pending | approved | denied | expired
|- reviewedBy?, reviewedByDisplay?, decisionReason?
|- expiresAt (10 min default), reviewedAt?
+- createdAt, updatedAt: Timestamp
NotificationsSomente dashboard
Sistema unificado de notificações com 60+ tipos em 8 categorias. Notificações no aplicativo entregues via assinaturas em tempo real do Firestore; e-mail via Resend; despacho de webhooks para Slack/Discord/Teams. Hook de caixa de entrada unificada mescla menções + alertas no aplicativo em todas as orgs. Gerencie em Dashboard → Notifications.
Documento de notificação no aplicativo
userId(destinatário),orgId,typetitle,message,link?data?: primitivos do Firestore (string | number | boolean)read: boolean,readAt: Timestamp | null
Documento de menção em comentário de trace
recipientUid,type(trace_mention | comment_reply | room_mention | pin_mention)payload: commentId, entityType, entityId, entityLabel, actorUid, actorName, snippet (~120 caracteres)- Opcional: parentRoomId, traceId, traceSource, traceLabel
77 tipos em 8 categorias
- billing (19): credits_low, quota_exceeded, subscription_*, billing_addon_*, referral_reward
- mission_control (20): alert_rule_triggered, channel_error, byok_unhealthy, approval_requested, bot_budget_*
- team (15): join_request, member_joined, page_access_*, member_role_changed
- system (12): welcome, onboarding_step, kb_indexing_*, bot_deleted, bot_import_completed, bot_import_needs_attention, timezone_unset
- retention (4): retention_warning, retention_deleted, dormancy_*
- edge_cases (4): edge_case_alert, guardrail_triggered, red_team_run_complete, fix_proposal_applied
- broadcasts (2): broadcast, broadcast_failed · evolution (1): evolution_alert
Canais de entrega (4)
- No aplicativo: assinaturas em tempo real do Firestore (<100ms)
- E-mail: Resend (e-mails de menção, boas-vindas; opt-in por membro)
- Webhooks: Slack, Discord, Teams, genérico (2 tentativas, backoff de 500ms, timeout de 8s)
- Ferramentas de bot: ferramentas de runtime
send_notification__{slug}__{id}(best-effort)
Caixa de entrada unificada em tempo real
useNotificationInbox(): mescla menções + no aplicativo, com escopo na org ativa- Assinaturas paralelas do Firestore por org; outros workspaces aparecem como contagens de não lidos + opção de alternância
- Expõe: items[], unreadCount, otherOrgUnread[], loading, markItemRead, markAllRead, deleteItems
- Máx. 100 por org por assinatura
Ciclo de vida e gatilhos
- Criado (read=false) → Marcar como lido → Excluir (exclusão permanente)
- Marcar todos como lidos: limitado a 200 documentos por chamada
- Gatilhos: escalonamentos de guardrail, anexos degradados, alertas de observabilidade, solicitações de entrada, transmissões, menções, boas-vindas
- Gatilhos do mecanismo são pós-hooks do tipo fire-and-forget (nunca bloqueiam a resposta do bot)
Canais de notificação (Mission Control)
- Tipos: slack, email, webhook, discord, teams
config: webhookUrl?, emails?, headers?events[]: quais eventos de alerta acionam este canalbotIds?: vinculação opcional de bot- lastUsedAt, lastStatus (success | failed)
RBAC e preferências
- No aplicativo: leitura = userId == auth.uid; atualização = apenas campos read/readAt; exclusão = false (via API)
- Menções: leitura = orgMember + correspondência de recipientUid; criação = actorUid == auth.uid
- Canais: leitura = membro; criação/atualização/exclusão = admin+
- API de despacho: operador+ obrigatório
- Preferências:
notificationPrefs.mentionEmail(padrão true)
Endpoints da API
- POST /api/notifications/create — distribuição para múltiplos destinatários (30/min por organização, máx. 500 destinatários)
- POST /api/notifications/delete — exclusão permanente (máx. 100 itens, propriedade verificada)
- POST /api/notifications/dispatch — despacho de webhook do Mission Control (10/min por organização, operador+)
- POST /api/notifications/email — e-mails de menção via Resend
- POST /api/notifications/welcome — boas-vindas únicas + e-mail (proteção transacional)
Criar: tipo (validado pelo registro), título, mensagem, link?, dados?, público (all_members|admins|{userIds}). Despacho: canais[], alerta{ruleName, gravidade, gatilho, mensagem, botName, conversationId, detalhes}.
Estrutura do Firestore
organizations/{orgId}/inAppNotifications/{notificationId}
|- userId, orgId, type (from registry)
|- title, message, link?, data?
|- read: boolean, readAt: Timestamp | null
+- createdAt: Timestamp
organizations/{orgId}/notifications/{notifId} (trace comment mentions)
|- recipientUid, type (trace_mention | comment_reply | room_mention | pin_mention)
|- read: boolean
+- payload: { commentId, entityType, entityId, entityLabel,
actorUid, actorName, snippet, parentRoomId?, traceId? }
{envRoot}/notificationChannels/{channelId} (Mission Control)
|- name, type (slack|email|webhook|discord|teams), enabled
|- config: { webhookUrl?, emails?, headers? }
|- events[], botIds?, lastUsedAt, lastStatus
+- createdBy, createdAt, updatedAt
organizations/{orgId}/members/{uid}.notificationPrefs:
{ mentionEmail: boolean (default true) }