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

  1. 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.
  2. 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.
  3. 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.
  4. 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

  1. Auto (padrão) — a chave nativa do provedor do modelo quando adicionada (direta, por exemplo, api.anthropic.com), caso contrário, sua chave OpenRouter.
  2. Sempre OpenRouter — todo chat executa com sua chave OpenRouter, mesmo quando uma chave direta existe.
  3. Somente chaves nativas — OpenRouter nunca é usado; modelos sem chave direta ficam bloqueados.
  4. 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 nativo generateContent)
  • 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étodoCaminhoDescrição
POST/api/v1/bot-runExecuta um turno de bot ou grupo de agentes (escopo: respond)
POST/api/v1/kb/queryConsulta uma conexão de base de conhecimento (escopo: kb:read)
POST/api/v1/kb/documentsEnvia documentos para uma fonte de KB (escopo: kb:write)
POST/api/v1/tests/gateA execução de teste do bot passa pelo portão de lançamento? Para CI (escopo: tests:read)
GET/healthVitalidade (processo ativo)
GET/readyProntidão (pode lidar com solicitações)
GET/liveSonda de uptime
GET/flagsSinalizadores 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

CampoTipoDescrição
botIdstringIdentificador do bot (do Dashboard → Bots). É necessário botId ou groupId.
messagestringA mensagem atual do usuário final

Campos Opcionais

CampoTipoDescrição
groupIdstringID do grupo de agentes (executa uma equipe multi-bot em vez de um único bot)
conversationHistoryobject[]Turnos anteriores: { role: 'user' | 'assistant', content }
sessionIdstringID da conversa/sessão; ecoado de volta como conversationId
endUserExternalIdstringID estável do usuário final no seu namespace (≤256). Obrigatório para nome de exibição / e-mail.
endUserDisplayNamestringNome legível mostrado em Rastreamentos (≤200)
endUserEmailstringE-mail do usuário final para transferência de suporte (validado)
known_factsobject[]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.
channelstringapi (padrão) | widget | whatsapp | slack | unknown
modelstringSubstituição de modelo (ex.: openai/gpt-4.1-mini, anthropic/claude-sonnet-4.6)
maxTokensnumberMáximo de tokens de saída para este turno
temperaturenumberTemperatura de amostragem para este turno
disableToolsbooleanDesativa chamadas de ferramenta/conector para este turno
maxToolIterationsnumberLimita as iterações do loop de chamadas de ferramenta
responseFormatobjectSaída estruturada: {type:"json_object"} ou {type:"json_schema", json_schema:{...}} — restringe a resposta final (somente modelos compatíveis com OpenAI)
streambooleanStreaming 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

CampoDescrição
responseO texto da resposta do assistente para mostrar ao usuário
runIdID exclusivo deste turno — encontre-o no Dashboard → Rastreamentos
conversationIdEcoa o sessionId da solicitação
modelO modelo que realmente atendeu ao turno
latencyMsLatência do turno no lado do servidor (ms)
tokensContagens 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
toolCallsFerramentas invocadas neste turno (nome, disposição, latência, custo)
sessionEndDefinido quando o bot encerrou a sessão ({ reason, summary? })
kbTelemetria de fundamentação de KB, incluindo citações (quando a recuperação foi executada)
pendingApprovalPresente 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.

PlanoMensalRespostas do bot
Free$0Uso justo
Lite$40Uso justo
Pro$100Uso justo · guia ≈ 100K/mês
EnterprisePersonalizadoDefinido 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

PlanoPreçoLimites principaisObservações
Free$01 bot · retenção de rastreamento de 7 diasSua própria chave de IA, sem margem; respostas do bot são uso justo
Lite$403 bots · retenção de rastreamento de 14 diasKit para criadores individuais; sem suíte avançada de IA ou Broadcasts
Pro$10025 bots · retenção de rastreamento de 90 diasSuíte avançada de IA + Broadcasts
EnterprisePersonalizadoNegociadoDPA 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çalhoSignificado
X-RateLimit-LimitCapacidade de requisições por minuto da chave
X-RateLimit-RemainingRequisições restantes na janela atual de limite de taxa
X-RateLimit-ResetSegundos Unix quando a janela reinicia
Retry-AfterSegundos para esperar antes de tentar novamente (em 429)
Idempotent-Replaytrue 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 rebaixado
  • requireQuota — uso ≥ limite do plano
  • requireProviderKey — recurso de IA precisa da sua própria chave de LLM (BYOK, gratuito)
  • requireStorageEventsBudget — pool de armazenamento esgotado
  • Retorna PlanAccessError com upgradeTarget

Arquitetura de outbox durável

  • As rotas de API publicam em um billingOutbox durável antes do Pub/Sub
  • A Cloud Function billingOutboxWorker é o único gravador de conta
  • Transações atômicas com idempotência + clamp negativo
  • O billingReconciliation diá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étodoCaminhoDescrição
GET/v1/traces/{trace_id}/replayPayload 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=50Lista cada execução em uma sessão, mais recentes primeiro
GET/v1/analytics/companies/{company_id}/overview?limit=500&top_n=10Taxa de escalonamento, latência média e agregações de tokens/custos na janela
GET/v1/analytics/companies/{company_id}/runs?limit=100Execuçõ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-rows agregaçõ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_spend
  • environment: production, test, ou null para ambos; botId null = 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 minTraces respostas e, em seguida, aguarda cooldownMinutes

Funções

  • analytics.view — visualizador
  • analytics.edit, analytics.annotate — operador
  • analytics.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

ChavePadrãoDescrição
{{company_name}}Acme CorpO nome da empresa do cliente
{{user_name}}JohnO nome de exibição do usuário final
{{product_name}}Widget ProO produto em discussão
{{industry}}TechnologyO setor vertical do cliente
{{tone}}professionalTom da resposta (formal, casual, empático)
{{language}}EnglishIdioma da resposta
{{max_length}}256Comprimento 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çãoPadrãoDescrição
EstratégiaOPROQual algoritmo de otimização usar
Métrica de AvaliaçãoTaxa de Sucessosuccess_rate | verification_pass | user_satisfaction | latency
Frequência de ExecuçãoDiáriahourly | daily | weekly | manual
Auto-PromoçãoDesativadoPromover automaticamente variantes vencedoras para ativas
Limiar de Melhoria2%Melhoria mínima necessária para se qualificar como vencedor
Máx. de Variantes por Execução5Número de variantes candidatas geradas por execução de otimização
Tamanho Mínimo da Amostra50Solicitaçõ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

  1. Varredura de traces — POST /v1/edge-cases/{org}/scan arquiva 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
  2. 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)
  3. 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

  1. Observar — amostrar traces recentes do bot
  2. Detectar — agrupar falhas e quase-erros
  3. Inferir — LLM revisor nomeia o padrão e a causa raiz
  4. Gerar — criar rascunho de regra, edição de prompt ou guardrail
  5. Injetar — anexar ao bot atrás de uma flag de experimento
  6. 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 draft ou 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, description
  • mode: guiado | estrito
  • start_step_id: etapa de entrada (deve ser definida)
  • steps: FlowStep[]
  • enabled: booleano

Estrutura de etapa (FlowStep)

  • id (único), name
  • goal: injetado no prompt do sistema para esta etapa
  • collect: informações a solicitar antes de avançar — o fluxo mantém o que a coleta de dados do bot não consegue salvar
  • allowed_tools: string[] | "all" | "none" — aplicado no modo estrito, orientação no guiado
  • allowed_agent_id: subagente para esta etapa (grupos)
  • terminal: encerra o fluxo

Transição

  • to: id da etapa de destino
  • kind: sempre | dados_completos | intenção | condição | resultado_da_ferramenta
  • intent (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_id
  • visited: ids de etapas vistos nesta sessão
  • done: o fluxo atingiu uma etapa terminal
  • data: 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 /attach para 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 .../versions lista 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 tipo
  • increment, max, min — números (máx/mín também datas)
  • append, append_unique — listas
  • merge — 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}/configOs 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}/revisionsHistórico, mais recente primeiro
POST/api/v1/state/{botId}/records/{scope}/{subjectId}/restoreRestaurar 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}/configSubstituir 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_busy com Retry-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 remember e forget), 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}/memoriesLembrar 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}/searchPesquisar 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ágioQuandoVocê pode responder
on_session_startPrimeira mensagem de uma conversacontexto, instruções, estado
before_turnCada mensagem, antes do modelocontexto, instruções, estado, resposta, bloqueio
retrieveCada mensagem, junto com a base de conhecimentopassagens
after_turnApós o bot responder, antes do envioresposta, estado, endConversation
on_session_endUma 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 — true ou {"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}/endEncerra; a próxima mensagem da pessoa inicia uma nova
POST/api/v1/sessions/{sessionId}/forkUma 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, legacy ou dashboard
  • 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

PlanoMáx. de datasetsMáx. de traces preservados
Free150
Starter1200
Lite105.000
Pro5025.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órios
  • clientName (1-200), redirectUris []
  • grantTypes: authorization_code, refresh_token
  • tokenEndpointAuthMethod: none | client_secret_post
  • clientSecretHash: 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, KB
  • rylvo:write — criar/atualizar bots, prompts, conhecimento, configurações
  • rylvo: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.clientId por 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étodoCaminhoDescrição
POST/v1/connectorsCriar 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}/activateAtivar
POST.../{id}/deactivateDesativar
POST.../{id}/testTestar endpoint
POST/v1/connectors/generate-secretGerar segredo HMAC
GET/v1/connectors/{company_id}/tools/availableListar 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)
  • enabled permitido 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 botId e channelType

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

RecursoLeituraGravaçãoExclusão
Botsbots.list, bots.getbots.create, bots.updatebots.delete
Promptsprompts.list, prompts.getprompts.create, prompts.update, prompts.set_optimizationprompts.delete
Guardrailsguardrails.list, guardrails.getguardrails.create, guardrails.updateguardrails.delete
Testestests.list_cases, tests.list_runs, tests.get_run_resultstests.create_case, tests.run_suitetests.delete_case
Conectoresconnectors.list, connectors.getconnectors.create, connectors.update, connectors.testconnectors.delete
Canaischannels.list, channels.getchannels.create, channels.update, channels.register_webhook—
Servidores MCPmcp_servers.list, mcp_servers.getmcp_servers.register, mcp_servers.updatemcp_servers.delete
Habilidadesskills.list, skills.getskills.create, skills.updateskills.delete
Base de Conhecimentokb.list_connections, kb.get_connectionkb.create_connection, kb.update_connection, kb.add_sourcekb.delete_connection
Grupos de Agentesagent_groups.listagent_groups.create, agent_groups.add_botagent_groups.delete
Automaçõesautomations.list_tasks, broadcasts.listautomations.create_task, broadcasts.createautomations.delete_task, broadcasts.delete

Ferramentas macro

  • scaffold_bot_from_description — criar um bot + prompt de sistema + guardrail inicial a partir de uma descrição
  • clone_bot — duplicar um bot e opcionalmente copiar recursos vinculados
  • attach_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 testDatabaseName opcional
  • Chave de circuit-breaker separada — tabelas de teste ausentes nunca afetam a entrega ao vivo
  • Payloads de webhook incluem source e isTest
  • 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/k navegação, Enter inspeçã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 finais
  • retentionPolicy: { 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, addedAt
  • snapshot: 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: PlanAccessError code="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ário
  • audit.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 humanos
  • keyPrefix — primeiros 12 caracteres para exibição
  • keyHash — SHA-256 da chave bruta (nunca armazene a chave bruta)
  • environment — production | test (staging/development legados mapeiam para test)
  • permissions — array de escopos de API
  • rateLimitOverride — 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-poll
  • kb:read — POST /api/v1/kb/query
  • kb:write — POST /api/v1/kb/documents
  • tests:read — POST /api/v1/tests/gate
  • trace.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 evento
  • approve() — verifica pending, atualiza, registra, idempotente
  • deny() — verifica pending, atualiza + motivo, registra, idempotente
  • list_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, type
  • title, 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 canal
  • botIds?: 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) }