Skip to main content

Automated test framework for AtendentePro chatbot agents

Project description

MonkAI Tester

Framework de testes automatizados para agentes de chatbot construídos com AtendentePro e OpenAI Agents SDK.

Valida respostas, tool calls, parâmetros e roteamento entre agentes, gerando relatórios de KPI com métricas de desempenho.

Usar em outro repositório?Guia: uso em outro repositório (instalação, dados, comandos e CI para agentes de IA).


Instalação

# Uso básico (modo service)
pip install monkai-tester

# Modo local (instanciar agentes com AtendentePro)
pip install "monkai-tester[local]"

# Auto-fetch de secrets do Azure Key Vault (uso interno MonkAI)
pip install "monkai-tester[keyvault]"

# Servidor FastAPI opcional
pip install "monkai-tester[server]"

Extras:

  • [local] — instala atendentepro para rodar os agentes localmente.
  • [keyvault] — instala monkai-keyvault para buscar AZURE_OPENAI_* (e a license do AtendentePro) do Azure Key Vault automaticamente. Sem este extra, defina AZURE_OPENAI_KEY e AZURE_OPENAI_ENDPOINT no ambiente/.env. (monkai-keyvault é interno e não está no PyPI público.)
  • [server] — instala FastAPI/uvicorn para o monkai-tester-server.

O pacote no PyPI público é distribuído como wheels compilados com Cython (código-fonte protegido), com builds para Linux, macOS e Windows em Python 3.11–3.13.


Ativação (licença)

A biblioteca requer um token de licença para uso (igual aos demais produtos MonkAI). Sem ativação, rodar o tester levanta LicenseNotActivatedError.

# via variável de ambiente (auto-ativa no import)
export MONKAI_TESTER_LICENSE_KEY="MTK_..."
# ou via código
from monkai_tester import activate
activate("MTK_...")
  • monkai-tester --help funciona sem licença.
  • Para obter um token, contato: contato@monkai.com.br.
  • Uso interno MonkAI: a chave vive no Azure Key Vault (MONKAI-TESTER-LICENSE-KEY).

Estrutura do pacote

O pacote monkai-tester expõe o comando monkai-tester (ou python -m monkai_tester). A estrutura do código-fonte no repositório é:

src/monkai_tester/
  __init__.py
  __main__.py                    # Permite rodar com python -m monkai_tester
  tester_local_service.py        # Orquestrador principal (entry point)
  utils.py                       # Leitura do CSV, execução do test suite, salvamento
  process_interaction.py         # Interação unificada (local via Runner.run / service via HTTP)
  validation_engine.py           # Motor de validação em 5 camadas (+ guardrail)
  match_answer_agent.py          # 7 agentes GPT de comparação semântica
  kpi_generator.py               # Geração de relatório de KPIs em JSON
  prompt_selector_flow.py        # Resolve a network do cliente (entry-point / manifesto) p/ modo local
  print_interactions_message.py  # Formatação de output no terminal
  check_atendentepro_license.py  # Validação da licença AtendentePro

Os casos de teste ficam em um diretório que você indica com --data-dir. Dentro dele, crie uma subpasta por cliente. O CSV de cada cliente pode ter um dos nomes (por ordem de preferência): Desempenho_<client>.csv (ex.: Desempenho_acme.csv), Desempenho_agentes_local.csv, ou ser o único arquivo .csv na pasta do cliente.

<data-dir>/
  acme/
    Desempenho_agentes_local.csv
  outro_cliente/
    Desempenho_outro_cliente.csv

Os resultados (CSV e JSON de KPI) são gravados em --output-dir (padrão: ./results).


Como funciona

Visao geral do fluxo

CSV de casos de teste (;-separated)
        |
        v
  utils.load_input_file()         -- le o CSV e retorna TestCaseRow[]
        |
        v
  utils.run_test_suite()          -- itera por grupo de ID, executa cada interacao
        |
        |--- modo "local"  --> process_interaction.process_interaction_local()
        |                        usa Runner.run() do OpenAI Agents SDK
        |                        contra a network do agente real
        |
        |--- modo "service" -> process_interaction.process_interaction_service()
        |                        envia HTTP POST para o endpoint deployado
        |
        v
  validation_engine.validate_test_case()   -- valida cada resposta em 5 camadas
        |
        |--- match_answer_agent3  --> compara parametros (GPT)
        |--- match_answer_agent5  --> compara nomes de tool calls (GPT)
        |--- match_answer_agent6  --> compara sender/agent name (GPT)
        |--- match_answer_agent4  --> compara conteudo semanticamente (GPT)
        |--- match_answer_agent7_guardrail --> compara veredito do guardrail (GPT)
        |
        v
  utils.save_results()            -- salva CSV de resultados
        |
        v
  kpi_generator.generate_comprehensive_report()  --> detailed_kpi_report.json

Modos de execucao

Modo Descricao Requer atendentepro? Requer endpoint deployado?
service Envia HTTP POST para o endpoint real (Azure Functions) e valida a resposta Nao Sim
local Instancia a network do agente localmente via Runner.run() e valida a resposta Sim Nao
both Executa primeiro local, depois service Sim Sim
auto Usa a coluna Type do CSV para decidir (Local ou Service) por grupo Depende Depende

Validacao em 5 camadas

Cada interacao passa pelas seguintes verificacoes (na ordem):

  1. Parametros -- os argumentos da tool call correspondem aos esperados? (via match_answer_agent3)
  2. Tool calls -- o nome da ferramenta chamada e o esperado? (via match_answer_agent5)
  3. Sender -- o agente que respondeu e o esperado? (via match_answer_agent6)
  4. Conteudo -- a resposta textual e semanticamente equivalente a esperada? (via match_answer_agent4)
  5. Guardrail -- o comportamento do agente bate com o veredito de guardrail esperado (decision / risk_level / category)? (via match_answer_agent7_guardrail)

Cada camada e pulada automaticamente quando o valor esperado esta vazio no CSV.

Quando a coluna Tester AI esta como TRUE, a comparacao e feita por um agente GPT (gpt-4.1 por padrão; configurável via AZURE_OPENAI_DEPLOYMENT). Se FALSE, a comparacao e feita por igualdade exata de string (vale para as 4 primeiras camadas; a camada de guardrail sempre roda via GPT por ser semantica).

Camada de guardrail e os 5 buckets do paper

A camada 5 implementa o framework descrito no paper "Static vs Specialist Guardrails" da MonkAI Research, que avalia guardrails em 5 buckets:

Bucket Tema
B1 Ataques (jailbreak, prompt injection, system prompt leak)
B2 PII / policy violation (CPF, CID, dados medicos, credenciais)
B3 Off-topic benigno (bitcoin, piadas, programacao, esporte)
B4 In-scope canonical (greetings, billing, scheduling, knowledge)
B5 Edge cases (short follow-up, language mix, sarcasm, ambiguo)

Cada caso de teste pode declarar um veredito esperado em 4 colunas opcionais do CSV:

Coluna Valores Default
Bucket B1 / B2 / B3 / B4 / B5 vazio
Guardrail_Decision allow / warn / escalate / block vazio (camada pulada)
Guardrail_Risk_Level none / low / medium / high / critical none
Guardrail_Category texto livre (ex: prompt_injection, pii_cpf) vazio

O KPI report agrega resultados por bucket (per_bucket) e expoe a taxonomia de falhas no campo failure_dimensions:

"failure_dimensions": {
  "tool_failure": 3,       // parameters ou tool_calls erradas
  "handoff_failure": 1,    // sender errado (roteamento entre agentes)
  "context_failure": 2,    // resposta divergente do esperado
  "guardrail_failure": 4   // veredito do guardrail inconsistente
}

Essa taxonomia e o sinal que o agent team /atendentepro-iterate usa para decidir em qual area da config aplicar o fix (tools / handoffs / prompts / politica de guardrail).

Agentes GPT de comparacao

O arquivo match_answer_agent.py contem 7 agentes especializados:

Agente Funcao Uso
Agent 1 Comparacao semantica ampla Disponivel para uso geral
Agent 2 Comparacao semantica estrita Disponivel para uso geral
Agent 3 Comparacao de parametros Usado pelo validation_engine (camada 1)
Agent 4 Comparacao de conteudo Usado pelo validation_engine (camada 4)
Agent 5 Comparacao de tool calls Usado pelo validation_engine (camada 2)
Agent 6 Comparacao de sender/agent Usado pelo validation_engine (camada 3)
Agent 7 Comparacao de veredito de guardrail Usado pelo validation_engine (camada 5)

Todos usam o deployment Azure OpenAI configurado via AZURE_OPENAI_DEPLOYMENT (default: gpt-4.1) com temperature=0 e retornam True ou False.


Sandbox (valide hipoteses de agente localmente)

O sub-comando sandbox roda cenarios curtos contra a rede real do cliente sem fazer deploy para dev. Use para validar fixes em ~30s / ~$0.02 por run.

Setup (uma vez)

# Variaveis obrigatorias (puxando do Key Vault)
export AZURE_OPENAI_KEY=$(az keyvault secret show --vault-name key-vault-monkai --name AZURE-OPENAI-KEY --query value -o tsv)
export AZURE_OPENAI_ENDPOINT=$(az keyvault secret show --vault-name key-vault-monkai --name AZURE-OPENAI-ENDPOINT --query value -o tsv)
export ATENDENTEPRO_LICENSE_KEY=$(az keyvault secret show --vault-name key-vault-monkai --name ATENDENTEPRO-LICENSE-KEY --query value -o tsv)
export ATENDENTEPRO_LICENSE_SECRET=$(az keyvault secret show --vault-name key-vault-monkai --name ATENDENTEPRO-LICENSE-SECRET --query value -o tsv)

# Instalar atendentepro no venv do monkai-tester
pip install atendentepro

Resolução da network (client-agnostic)

O sandbox não conhece nenhum cliente. A network de cada cliente é resolvida por um de dois mecanismos genéricos, que retornam uma AgentNetwork fresca:

Mecanismo Como expor no repo do cliente
Entry point monkai_tester.sandbox_networks <client> = "<pkg>.module:load_network" no pyproject.toml
Manifesto monkai_tester.networks.toml (na raiz passada por --monkai-services-root) tabela [sandbox_networks] com <client> = "dotted.module[:callable]"
# <services-root>/monkai_tester.networks.toml
[sandbox_networks]
acme = "acme_pkg.sandbox:load_network"

Onde vivem os scenarios

Os scenarios de cada cliente vivem no repositorio do cliente (nao aqui). Organize como preferir, por exemplo:

<repo-do-cliente>/.../<client>/sandbox/
├── scenarios/        # *.yaml scenarios
├── prompts/          # *.md prompt variants
└── reports/          # *.md run evidence

Rodar um scenario

cd /path/to/repo-do-cliente
monkai-tester-cli sandbox run .../sandbox/scenarios/group-62.yaml --monkai-services-root .

(--monkai-services-root aponta para a raiz com o monkai_tester.networks.toml; pode também vir de MONKAI_SERVICES_ROOT. Dispensável se o cliente registra via entry point.)

Esperado: tabela com sender match por turn + relatorio markdown em ../reports/.

Listar transformacoes disponiveis

monkai-tester-cli sandbox list-variants

Validar um cenario sem rodar

monkai-tester-cli sandbox validate <path-to-scenario.yaml>

Resposta da API em modo service

Para que a validação de Tool_calls e Parameters do CSV funcione em modo service, o endpoint pode retornar na resposta JSON os campos opcionais tool_calls e tool_parameters:

  • Onde: se a resposta tiver agent_response (formato Teams-style), o tester lê agent_response.tool_calls e agent_response.tool_parameters. Caso contrário, lê tool_calls e tool_parameters no objeto raiz da resposta.
  • tool_calls: lista de nomes de ferramentas (strings), ex.: ["minha_ferramenta"], ou lista de objetos com "name" e opcionalmente "arguments" (string JSON), ex.: [{"name": "minha_ferramenta", "arguments": "{\"x\": 1}"}].
  • tool_parameters (opcional): objeto com parâmetros agregados. Se não for enviado, os parâmetros podem ser derivados dos arguments dos objetos em tool_calls quando existirem.

Respostas sem esses campos continuam válidas; a validação de Tool_calls/Parameters só é feita quando o tester conseguir extrair tool_calls da resposta.


Como rodar localmente

Pre-requisitos

  1. Python 3.11+

  2. Azure Key Vault (obrigatório para as chaves Azure OpenAI): o tester busca do Key Vault (via monkai-keyvault) as chaves que ele usa e que existem no vault. Para essas chaves, o Key Vault tem prioridade sobre .env/ambiente.

    • Obrigatórias via Key Vault (Azure OpenAI): AZURE_OPENAI_KEY, AZURE_OPENAI_ENDPOINT
    • Também buscada do Key Vault (se existir): ATENDENTEPRO_LICENSE_KEY

    O restante pode ficar em .env/ambiente (por exemplo: AZURE_OPENAI_API_VERSION, AZURE_OPENAI_DEPLOYMENT, ATENDENTEPRO_LICENSE_SECRET, e as URLs de endpoint por cliente como ${<CLIENT>_API_URL}, etc.).

  3. Instalar o pacote (veja Instalação acima). Para modo local use pip install monkai-tester[local].

Testar contra o endpoint em producao

O modo service envia cada mensagem do CSV para o endpoint HTTP (Azure Function). Para usar o endpoint de producao:

  1. Configure no Azure Key Vault pelo menos AZURE_OPENAI_KEY e AZURE_OPENAI_ENDPOINT. As URLs do modo service (${<CLIENT>_API_URL}) podem estar no .env se você preferir.

  2. Execute em modo service (o placeholder ${<CLIENT>_API_URL} do CSV é substituído automaticamente pelo valor da variável). É obrigatório informar o diretório dos dados com --data-dir:

monkai-tester --mode service --client acme --data-dir /caminho/para/data

Ou com o módulo Python:

python -m monkai_tester --mode service --client acme --data-dir /caminho/para/data

Para qualquer cliente, configure a URL de endpoint correspondente (<CLIENT>_API_URL) no Azure Key Vault ou no .env e use --client <client>. Não é necessário editar o CSV; os placeholders são resolvidos com os valores carregados do Key Vault/ambiente.

Comandos

O argumento --data-dir é obrigatório: deve ser o diretório base que contém uma subpasta por cliente (ex.: acme/), cada uma com um CSV (convenção: Desempenho_<client>.csv ou Desempenho_agentes_local.csv, ou um único .csv na pasta).

Testar todos os clientes em modo service

monkai-tester --mode service --client all --data-dir /caminho/para/data

Testar apenas um cliente em modo service

monkai-tester --mode service --client acme --data-dir /caminho/para/data

Testar em modo local (instancia os agentes diretamente)

Requer monkai-tester[local] e, em geral, --monkai-services-root apontando para o repositório que contém as networks dos agentes:

monkai-tester --mode local --client acme --data-dir /caminho/para/data --monkai-services-root /caminho/para/monkai_services

Testar ambos os modos (local + service)

monkai-tester --mode both --client all --data-dir /caminho/para/data --monkai-services-root /caminho/para/monkai_services

Usar um CSV customizado

monkai-tester --mode service --csv /caminho/para/meus_testes.csv --client acme --data-dir /caminho/para/data

Salvar resultados em diretório específico

monkai-tester --mode service --client all --data-dir /caminho/para/data --output-dir ./meus_resultados

Ajustar timeout e desabilitar TLS

monkai-tester --mode service --client all --data-dir /caminho/para/data --timeout 90 --skip-tls-verify

Limitar número de grupos de teste

monkai-tester --mode service --client all --data-dir /caminho/para/data --limit 5

Execução paralela de grupos (--workers)

Cada grupo de teste é uma conversa independente — só as interações dentro de um grupo dependem de ordem (multi-turn). Grupos não compartilham estado de sessão entre si, então podem rodar em paralelo. --workers N executa N grupos concorrentemente (default 1 = sequencial, comportamento inalterado):

# 3 grupos em paralelo (~3x mais rápido em service mode)
monkai-tester --mode service --client all --data-dir /caminho/para/data --workers 3

As interações de cada grupo continuam sequenciais (preserva o estado da sessão), e os resultados são sempre reordenados para a ordem original do CSV, independente da ordem de conclusão.

Benchmark de múltiplos modelos

Roda a suite completa para cada modelo listado. Em service mode, passa model_override no payload HTTP:

monkai-tester --mode service --client acme --data-dir /caminho/para/data --models gpt-4.1 gpt-4o-mini gpt-5-mini

Cada modelo gera seu próprio CSV e JSON de KPI, nomeados com o label do modelo.

Isolar sessões com session-prefix

Prefixa campos de identificação do usuário no payload para evitar contaminação de sessão entre testes paralelos. Quais campos são prefixados é configurável via --session-prefix-fields (dot-notation):

# Teams-style (default: from.email, from.aadObjectId, from.id)
monkai-tester --mode service --client acme --data-dir /caminho/para/data --session-prefix bench-4o

# WhatsApp-style (prefixar sender_phone)
monkai-tester --mode service --client acme --data-dir /caminho/para/data --session-prefix bench-4o --session-prefix-fields data.sender_phone

# Generic webhook (prefixar user.email e user.id)
monkai-tester --mode service --client acme --data-dir /caminho/para/data --session-prefix bench-4o --session-prefix-fields user.email user.id

# Automático em benchmark mode (--models): cada modelo recebe prefix baseado no nome
monkai-tester --mode service --client acme --data-dir /caminho/para/data --models gpt-4o gpt-4.1
# gpt-4o → prefix "gpt4o", gpt-4.1 → prefix "gpt41"

Todos os argumentos CLI

Argumento Valores Default Descrição
--mode local, service, both, auto service Modo de execução
--client nome do cliente (subpasta em --data-dir) ou all all Cliente a testar
--data-dir caminho para diretório (obrigatório) Diretório base com subpastas por cliente e CSVs
--csv caminho para arquivo (auto por cliente) CSV específico (sobrescreve lookup por cliente)
--output-dir caminho para diretório ./results Diretório para resultados e relatório KPI
--timeout float (segundos) 60.0 Timeout HTTP para modo service
--skip-tls-verify flag false Desabilita verificação TLS
--limit inteiro (nenhum) Executa apenas os primeiros N grupos de teste (por ID)
--workers inteiro >= 1 1 Número de grupos a executar concorrentemente (1 = sequencial). As interações dentro de cada grupo permanecem sequenciais para preservar o estado da sessão; o resultado é sempre reordenado para a ordem original do CSV. Ex.: --workers 3
--monkai-services-root caminho (nenhum) Caminho para monkai_services (recomendado para modo local)
--models lista de specs (nenhum) Benchmark: roda a suite completa para cada modelo. Formato: model[:provider[:base_url:api_key]]. Em service mode, passa model_override no payload HTTP. Em local mode, reconfigura o AI provider. Ex.: --models gpt-4.1 gpt-4o-mini
--session-prefix string (nenhum) Prefixa campos de identidade no payload para isolar sessões. Campos configuráveis via --session-prefix-fields. Em benchmark mode (--models), auto-gera prefix por modelo. Ex.: --session-prefix bench-4o
--session-prefix-fields lista de paths from.email from.aadObjectId from.id Paths dot-notation dos campos a prefixar. Ex.: --session-prefix-fields data.sender_phone (WhatsApp-style) ou user.email user.id (generic webhook)
--service-client-id string (nenhum) Em modo service, anexa ?client_id=<id> à API URL (exigido por adapters Teams-style que roteiam por client_id)
--tool-match-mode exact, set exact Modo de matching da camada de tool calls. exact mantém o comportamento legado (juiz LLM ou comparação exata de string, sensível a contagem/sequência). set compara o conjunto de nomes DISTINTOS de forma determinística: repetições da mesma tool colapsam (1 ou 2 calls de query_data casam igual), mas tool errada ou extra continua reprovando. A coluna Tool_match_mode do CSV sobrescreve por linha
--groundedness-shadow caminho NDJSON (nenhum) Junta o shadow log de groundedness_verdict do engine (NDJSON, 1 JSON por linha) ao KPI do run como bloco medido per_bucket_groundedness. Join por session_id ↔ âncora da suite (ver --groundedness-session-field); prefixos de --session-prefix são absorvidos por suffix-match. O arquivo é lido APÓS a suite terminar — colete os logs do engine durante o run. Arquivo ausente = warning, nunca falha o run
--groundedness-session-field dot-path data.sender_phone Campo do DATA_TEMPLATE que ancora o join de session_id do --groundedness-shadow

Exit code

O processo retorna 0 se todos os testes passaram e 1 se algum falhou. Isso permite uso em CI/CD para falhar o pipeline automaticamente.


Formato do CSV de casos de teste

O CSV usa separador ;. Cada linha representa uma interacao de uma conversa. Linhas com o mesmo ID compoem uma sequencia de conversa (multi-turn).

Coluna Descricao
Test TRUE/FALSE -- se a linha deve ser executada
Tester AI TRUE/FALSE -- se a validacao usa agente GPT (semantica) ou comparacao exata
Type Local ou Service -- usado quando --mode auto
API_URL URL do endpoint para modo service
HEADERS Cabecalhos HTTP (dict Python como string)
DATA_TEMPLATE Template JSON do corpo da requisição; User_message é injetado em attachments[0].content (Teams-style), data.text (WhatsApp-style) ou message (generic webhook), por ordem de precedência
Repeat Numero de repeticoes do teste
ID Identificador do grupo de conversa (linhas com mesmo ID = mesma conversa)
Label Rotulo livre para identificar o teste
First_message Primeira mensagem da conversa (ex.: token de reset de sessao)
User_message Mensagem do usuario para aquela interacao
Agent_From Agente de origem esperado
Agent_to Agente de destino esperado (usado na validacao de sender)
Tool_calls Nome da ferramenta esperada
Tool_match_mode (opcional) exact ou set -- sobrescreve --tool-match-mode para esta linha; vazio usa o modo global
Parameters Parametros esperados na chamada da ferramenta
Interaction Numero sequencial da interacao dentro do grupo
AI_message_official Resposta esperada do agente (usada na validacao de conteudo)
Agent_File Arquivo .py do agente (usado pela UI, opcional)
Agent_Name Nome do objeto do agente (usado pela UI, opcional)

Placeholders no CSV

Qualquer valor no CSV (API_URL, DATA_TEMPLATE, HEADERS, etc.) pode usar placeholders no formato ${NOME_VAR}. Eles são substituídos em tempo de execução pela variável de ambiente de mesmo nome (os.environ.get("NOME_VAR", "")). Exemplo: ${ACME_API_URL}. Nenhum cliente precisa de código específico: defina a variável no ambiente ou no Key Vault e use no CSV (ex.: API_URL = "${ACME_API_URL}").


Saidas geradas

Após a execução, o diretório de output (default ./results ou o valor de --output-dir) conterá:

1. CSV de resultados

Arquivo: results_{client}_{mode}_{timestamp}.csv

Contem uma linha por interacao testada com todas as colunas de entrada e validacao:

Coluna Descricao
test_id ID do grupo
label Rotulo do teste
interaction Numero da interacao
user_message Mensagem enviada
expected_message Resposta esperada
actual_message Resposta real do agente
expected_sender / actual_sender Agentes esperado e real
expected_tool_calls / actual_tool_calls Tool calls esperadas e reais
parameters_match True / False / None
tool_calls_match True / False / None
sender_match True / False / None
content_match True / False / None
overall_pass True se todas as camadas passaram
errors Descricao dos erros encontrados
latency_seconds Tempo de resposta
input_tokens / output_tokens Uso de tokens

2. Relatorio de KPI

Arquivo: detailed_kpi_report_{client}_{mode}_{timestamp}.json

Exemplo de conteudo:

{
  "generated_at": "2026-03-04T14:30:00Z",
  "overall": {
    "total_interactions": 7,
    "passed": 5,
    "failed": 2,
    "pass_rate": 0.7143,
    "fail_rate": 0.2857
  },
  "error_distribution": {
    "content_failures": 1,
    "sender_failures": 1,
    "tool_call_failures": 0,
    "parameter_failures": 0
  },
  "latency": {
    "mean_seconds": 3.45,
    "median_seconds": 2.80,
    "p95_seconds": 7.12,
    "max_seconds": 8.50,
    "min_seconds": 0.95
  },
  "token_usage": {
    "total_input_tokens": 12500,
    "avg_input_tokens": 1785.7,
    "total_output_tokens": 3200,
    "avg_output_tokens": 457.1
  },
  "per_test_group": [...],
  "per_agent": [...]
}

Publicação (CI/CD)

O pacote é publicado em dois canais, ambos disparados em push para main quando a versão em pyproject.toml muda:

Canal Workflow Formato Uso
PyPI público .github/workflows/publish.yml Wheels Cython-compilados (Linux/macOS/Windows × Python 3.11–3.13), código-fonte protegido pip install monkai-tester para qualquer consumidor
Azure Artifacts .github/workflows/publish_azure.yml py3-none-any pure-Python (MONKAI_TESTER_SKIP_CYTHON=1) Consumo interno rápido (Railway, subagents /atendentepro-iterate)

.github/workflows/ci-deploy-ready.yml roda os checks (ruff + pytest) antes de publicar, em modo pure-Python.

macOS arm64: o Cython não cross-compila no CI. Esses wheels são buildados localmente e enviados ao PyPI manualmente (ver "Release Process" no CLAUDE.md). Cada wheel passa por scripts/verify_wheel.py (garante zero vazamento de .py-fonte).

Secrets necessários no GitHub

Secret Para Descrição
PYPI_API_TOKEN PyPI público API token com escopo no projeto monkai-tester
AZURE_ARTIFACTS_PAT Azure Artifacts PAT com permissão Packaging (Read & Write)
AZURE_ORG Azure Artifacts Organização no Azure DevOps
AZURE_PROJECT Azure Artifacts Projeto (ex.: MonkAI)
AZURE_FEED Azure Artifacts Feed (ex.: strava_feed)

Para rodar os testes (modo service ou local) em outro repositório ou em CI, use os mesmos secrets e variáveis descritos na seção Pré-requisitos (AZURE_OPENAI_KEY, AZURE_OPENAI_ENDPOINT, as URLs de endpoint por cliente ${<CLIENT>_API_URL}, ATENDENTEPRO_*, etc.).


Clientes e resolução de network

O monkai-tester é uma biblioteca genérica e não carrega o nome de nenhum cliente. Em modo service basta uma subpasta por cliente em --data-dir com o CSV e a URL do endpoint resolvida por placeholder (${<CLIENT>_API_URL}).

Em modo local (instanciar a network via Runner.run()), o tester resolve a network do cliente por um de dois mecanismos genéricos — a fiação vive sempre no repositório do cliente, nunca aqui:

Mecanismo Quando usar Como expor no repo do cliente
Entry point monkai_tester.networks Cliente é um pacote pip instalável Registrar no pyproject.toml: [project.entry-points."monkai_tester.networks"]<client> = "<pkg>.tester_plugin:load_network"
Manifesto Cliente vive em disco (ex.: app de Azure Functions), acessado via --monkai-services-root Criar um monkai_tester.networks.toml na raiz, com uma tabela [networks] mapeando <client> = "dotted.module[:callable]" (callable default load_network)

O manifesto mantém o tester desacoplado do layout do consumidor: o caminho do módulo (ex.: client_resources.<client>.tester_network:load_network) vive no manifesto do cliente, nunca na biblioteca. Exemplo:

# <services-root>/monkai_tester.networks.toml
[networks]
acme = "acme_pkg.networks.acme:load_network"

Em ambos os casos, o loader não recebe argumentos e retorna (starting_agent, context). A configuração do Azure OpenAI e a ativação do AtendentePro são feitas pelo tester antes do loader rodar.


Como adicionar novos casos de teste

  1. Abra o CSV correspondente no seu --data-dir, em {client}/ (nome: Desempenho_{client}.csv ou Desempenho_agentes_local.csv, ex.: data/acme/Desempenho_agentes_local.csv ou data/acme/Desempenho_acme.csv).
  2. Adicione novas linhas seguindo o formato descrito acima.
  3. Para conversas multi-turn, use o mesmo ID e incremente a coluna Interaction.
  4. Defina First_message apenas na primeira interação (normalmente o token de reset como Monkai12345).
  5. Preencha as colunas de validação (Agent_to, Tool_calls, Parameters, AI_message_official) com os valores esperados.
  6. Colunas de validação vazias são ignoradas (a camada correspondente não é executada).

Exemplo: teste de conversa multi-turn

ID=10; Interaction=1; First_message=Monkai12345; User_message=Qual IVA de Energia?
ID=10; Interaction=2; User_message=Consumo; Agent_to=Interview Agent
ID=10; Interaction=3; User_message=ICMS; Agent_to=Answer Agent; AI_message_official=O codigo e E4

Troubleshooting

"ATENDENTEPRO - TOKEN INVÁLIDO" (modo local)

A licença do AtendentePro não foi aceita. Para validar a chave sem rodar os testes:

python -m monkai_tester.check_atendentepro_license

O script lê ATENDENTEPRO_LICENSE_KEY e ATENDENTEPRO_LICENSE_SECRET (do Key Vault ou do ambiente, conforme --source) e informa se a licença é válida. A partir da v0.6.20+ do atendentepro o SECRET é obrigatório. Configure-as no Azure Key Vault ou entre em contato com a MonkAI (contato@monkai.com.br) para obter um token válido.

"CSV not found"

Os CSVs devem estar no diretório indicado por --data-dir, em subpastas por cliente. Convenção de nome: Desempenho_<client>.csv ou Desempenho_agentes_local.csv, ou um único .csv na pasta do cliente. Verifique se --data-dir está correto ou use --csv para apontar para um arquivo específico.

"No starting_agent for local mode"

O modo local precisa instanciar os agentes. Verifique que atendentepro está instalado e que ATENDENTEPRO_LICENSE_KEY e ATENDENTEPRO_LICENSE_SECRET estão configurados no Azure Key Vault.

"GPT call failed" na validacao

A validação semântica usa Azure OpenAI (deployment configurado em AZURE_OPENAI_DEPLOYMENT). Verifique que AZURE_OPENAI_KEY e AZURE_OPENAI_ENDPOINT estão definidos e que o recurso tem o deployment correto.

Timeout em modo service

Aumente o timeout com --timeout 120 ou verifique se o endpoint esta acessivel. Use --skip-tls-verify se houver problemas de certificado.

Placeholders ${VAR} no CSV

Os CSVs podem conter placeholders no formato ${NOME_VAR} (ex.: ${ACME_API_URL}). Eles são substituídos pelos valores das variáveis de ambiente de mesmo nome ao carregar o CSV. Configure as variáveis no ambiente ou no Key Vault; variável não definida é substituída por string vazia.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

monkai_tester-0.17.0-cp313-cp313-win_amd64.whl (826.3 kB view details)

Uploaded CPython 3.13Windows x86-64

monkai_tester-0.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

monkai_tester-0.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl (5.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

monkai_tester-0.17.0-cp313-cp313-macosx_11_0_arm64.whl (928.6 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

monkai_tester-0.17.0-cp313-cp313-macosx_10_13_x86_64.whl (944.8 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

monkai_tester-0.17.0-cp312-cp312-win_amd64.whl (831.0 kB view details)

Uploaded CPython 3.12Windows x86-64

monkai_tester-0.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (6.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

monkai_tester-0.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl (5.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

monkai_tester-0.17.0-cp312-cp312-macosx_11_0_arm64.whl (936.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

monkai_tester-0.17.0-cp312-cp312-macosx_10_13_x86_64.whl (949.5 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

monkai_tester-0.17.0-cp311-cp311-win_amd64.whl (849.7 kB view details)

Uploaded CPython 3.11Windows x86-64

monkai_tester-0.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (6.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

monkai_tester-0.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl (6.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

monkai_tester-0.17.0-cp311-cp311-macosx_11_0_arm64.whl (935.6 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

monkai_tester-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl (964.7 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

File details

Details for the file monkai_tester-0.17.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 0ba1c5433991e72562f132838deb06dbd44270126e5fe58b76cfa11240c48bdd
MD5 3a00059cefb0b38d1427e175cf4fb328
BLAKE2b-256 1f2cb29faa975926ac86c8cd57226b3d3e20e4e7f8e5a45c949e95e834f59a75

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 38f892d61dd32462fec2eea4dce31d88c50d58af4a8140f44366b0d2aa4f1c4b
MD5 f72969767bf6a3436fe39c87071666c2
BLAKE2b-256 89086c66608b85bf9f6caa97bd0ae5f5bf20d541e15532bc6b208f4342146000

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 0e4dff771057c489da7a48769a67d0a90f681a4d7c10adc31cdf33de2a71fd6a
MD5 a84f43962fda93da7308c2bf62b1ae5d
BLAKE2b-256 63feef1cded40ef8ffc2a09082f105af1b7c6885f60f21f057ce412b6fbd43e3

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 31f399fec23b3f6ad35cf4965b66d914a53c563a5a3289134169bcfb699123aa
MD5 0e100e8e25912636da4739761174719b
BLAKE2b-256 fa0c4c5a8d32c02728c7d55c22177b0eecfcafab47979e2a6a294410b6443a38

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 f84c6b4999b9f53c6122d7419b3bf1dbd3b1fb1198356e07e5a1c1b4bd13e161
MD5 1c8017bbb3a598c894d07d92b40c3e45
BLAKE2b-256 3d1f61ee60c67499579c2d8146b5d8484f4e4c75dfd386f5f67162e97046917b

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2623fa15251bd5c7086ce39c9874ba839de6d4e6c9e3fb0c445f1381e3b54475
MD5 661cbe1436398e2b44a0057e4a982330
BLAKE2b-256 ce58d6c67f174b366cd463bdf6e7024b1a1ce2b2f56c7ffa54f2c7228e5396cc

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 127368ec9c59242bcfe04e45a9993a379eb4400fd52a237021339c6219e4ad20
MD5 1bb1fc35909e1613d44606056cd7dc49
BLAKE2b-256 bdd29c928c663660dec1b1ca9354d035ad8b0649c99827bc510da10de74e5933

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 b738a50ce351892ed7216fdc87b4103d4e2144bd46559f57db211745fb54a8d6
MD5 45a56e3128db401d9891d8a28644867b
BLAKE2b-256 175fb0097ad82cf0f94da450148db0a543817f6b48310b5a5fa3439ff39a3bc9

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 228c8e63554463e70f9f1a6100828d4dc6a50dc27ab1a87ae5c4b46abdebdee6
MD5 b11363f46655357bb87bc748e3458637
BLAKE2b-256 2e1f4f41b0cdd8ce058da25f5b9683f86c83dd5d02303cd224d3d21b35cc178d

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 e2c36a0a0026500d45d0530fef64a5000ae50e7f6fe0b80ab39b0157b79e7b79
MD5 ad14af3c5ce18b2fc7eb52747e04d0c5
BLAKE2b-256 256003c34a233f7a9c4d801085b5ca959227b996ca7392247998233c748ea605

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3e9d6b463a8fc1da0bc713801b8960e19453e1e64de5e2be9ad6e72e8ac197bc
MD5 cbb29033f645c3bc98c84501b1aa1584
BLAKE2b-256 026c72804ef4c057725339467762711fbd5536be421090ff98f4c12f7ecb6a30

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 be02c3692a369d7b69cac24a9083479df5fb233591a56793cda80b9bc0dc93fd
MD5 0e3595d55ba8695af79c1b6408dc3790
BLAKE2b-256 cc079ac292656912b7a5f21f8d04d5222cf971ff34d5af1c7147ab02b954cc3b

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 d43d905057b840a33a0443cae7bc740281899cdfc224279a393a8c1e8bd58953
MD5 7748c6b3b42d5a29fe3b29bcc2278d2a
BLAKE2b-256 ad9ec0aa46085279cac46d57f9f080a3333d1b981ef9626688238dad662dc561

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 db6eaae1a6016b2c1cb638d0c1eafe8615d65d7fc63cabf6e6ce0d870a5d6b0e
MD5 dd1026b4817cbd795b4707fba0a5073d
BLAKE2b-256 79a2ef424a53098ed7e97783c734d4be7c91e1db7d47dabd0d3542f237332168

See more details on using hashes here.

File details

Details for the file monkai_tester-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for monkai_tester-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d026e8ce2a1bc3922c4a74d01619155e67ac95a12340cf1ea9580f2145d8e3f5
MD5 a5e6cf304e5425f76f2cf5db4edae9c0
BLAKE2b-256 f4697a85b9dc11774754a3133abe25c957d94763fa47f67e8fb5eac8b3d76d23

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page