niadra é o SDK de Python: um cliente síncrono, Niadra, e um gêmeo assíncrono, AsyncNiadra, com os mesmos métodos. É de código aberto, sob Apache 2.0, pede Python 3.10 ou mais novo e depende só de httpx e pydantic. Cada método desta página corresponde a uma rota da referência da API.
Instalação
O cliente
AsyncNiadra recebe os mesmos argumentos, com http_client: httpx.AsyncClient. Uma instância por processo basta, e ela é segura entre threads. O cliente também funciona como gerenciador de contexto: sair do bloco chama close(), e um gancho de saída esvazia a fila por até dois segundos.
Propriedades
Seguro por padrão, estrito quando você pede
Sem chave, o cliente avisa uma vez e não faz nada. Cada método público captura e registra as próprias falhas e devolve um valor seguro: umContext vazio (veja context.error), um resultado vazio, False ou None. Os logs levam nome do método, status, código de erro e id da requisição, nunca handle nem texto. Com strict=True, as mesmas falhas levantam as exceções de Erros.
Tempo máximo
O SDK tem o próprio tempo máximo por método, independente do que a plataforma em volta permite.O cache de contexto
Dentro de uma conversa ou tarefa (uma chamada comconversation_id ou task_id), os contextos ficam em memória:
- com menos de 10 s: devolvidos sem requisição;
- até 10 minutos mais velhos: devolvidos na hora, enquanto uma requisição em segundo plano atualiza;
- quando uma requisição falha: o último contexto bom, se tiver menos de 30 minutos;
- no máximo 1.000 contextos, saindo primeiro o usado há mais tempo.
not_modified em vez do texto inteiro, e só uma atualização por contexto roda de cada vez. Um 401 ou 403 não é indisponibilidade: os contextos guardados saem (todos no 401, o pedido no 403), então cortar o acesso de um fornecedor corta também o que ele tinha em cache. Uma leitura comum e uma leitura com delta da mesma conversa dividem a mesma entrada, e cada delta é entregue uma vez só.
A fila de escrita
track(), action() e handoff() só enfileiram. Uma thread em segundo plano (uma task, no AsyncNiadra) manda um lote quando 15 itens estão esperando ou um segundo depois de o primeiro chegar, com três tentativas e espera crescente. Com a fila cheia, os itens novos são descartados e contados em dropped.
Handles
Handles identificam um sujeito num canal ou sistema. Os ajudantes são funções de primeiro nível que normalizam o valor e levantamValueError quando a entrada não pode ser válida, então um telefone malformado falha no ponto em que entra no seu código.
Todo método que recebe handle aceita também o modelo
Handle ou um dicionário com os campos dele ({"type": "phone_e164", "value": "+14155550123"}). Objetos entram como "invoice:erp:0823" ou como ObjectRef.
context()
O contexto de uma pessoa, de uma organização ou de um objeto de negócio. Corresponde aPOST /v1/context.
Devolve um
Context: todos os campos da resposta da API mais o que o SDK sabe da chamada.
search()
Busca no histórico inteiro de um sujeito, por palavra e por significado. Corresponde aPOST /v1/history/search.
Devolve um
SearchResult com items, recurrence (quantas vezes a mesma categoria aconteceu e como terminou a última), withheld, as_of, tokens_used, degraded e, em caso de falha, error.
timeline()
Uma página do histórico do sujeito, do mais recente para o mais antigo. Corresponde aPOST /v1/history/timeline.
limit vai de 1 a 100. Devolve uma TimelinePage com items, next_cursor, withheld, as_of e, em caso de falha, error. Passe next_cursor como cursor para continuar.
open()
Abre um episódio ou objeto encontrado porsearch() ou timeline(). Corresponde a GET /v1/history/items/{item_id}.
OpenedItem (summary, requested, promises, outcome, resolution, derived, timeline) ou None quando ele não está disponível. O trecho literal, excerpt, só volta para chaves com escopo elevado.
object_state() e object_timeline()
Leituras de um objeto de negócio. Correspondem aGET /v1/objects/{object_type}/{namespace}/{external_id} e à linha do tempo dele.
ObjectState traz ref, state, as_of, source_id, record_ref e as open_items. O estado vem só do que os sistemas de registro informaram; a ação de um agente conta quando um sistema a confirma. ObjectTimeline traz ref, items, next_cursor e as_of: eventos de sistema e ações de agente, do mais recente para o mais antigo, nunca o que alguém disse. Ids de objeto são ids de registro, não dado pessoal, então vão na URL; um id com barra não pode ser endereçado assim.
track()
Enfileira uma mensagem, um evento de sistema, uma ação ou qualquer outro item de lote, e volta na hora. Corresponde aPOST /v1/batch.
EventItem ou um dicionário com os campos dele. Um dicionário sem channel recebe o canal padrão do cliente; idempotency_key (um UUIDv7) e occurred_at (agora) são preenchidos quando você não passa. Use o id da mensagem no provedor como idempotency_key quando houver, para um lote repetido nunca duplicar nada. Devolve False quando o item foi descartado: inválido, impossível de serializar, fila cheia ou cliente desligado.
action()
Registra o que um agente fez num sistema de registro. Vai para a fila, comotrack().
A ação fica
declared até o sistema de registro confirmar com o próprio evento. Registrar ação exige o escopo act na chave.
identify()
Afirma que dois ou mais handles são do mesmo sujeito. Sai na hora, sem fila, para ocontext() seguinte enxergar; se a requisição falhar, o item vai para a fila de envio e o método devolve None.
verify()
Eleva o nível de verificação de uma conversa ou tarefa, depois que você provou. A Niadra nunca deduz o nível. Sai na hora, e o contexto guardado daquela conversa é descartado, para o próximocontext() já vir no nível novo.
method é otp_whatsapp, otp_sms, login, kba, network_attestation ou human_agent. Um nível acima do teto da fonte volta como erro de item verification_not_allowed.
feedback()
Corrige o que a Niadra derivou sobre um sujeito. Sai na hora e vira evento, então é auditado como qualquer outro. Corresponde aPOST /v1/feedback.
value vai até 2.000 caracteres e reason até 500. Devolve None quando a correção não pôde ser entregue.
upload_media()
Entrega um arquivo à Niadra, como a gravação de uma ligação, e devolve a referência para o evento. Mídia nunca viaja dentro do evento. Corresponde aPOST /v1/media/uploads.
upload_headers que a API devolveu, que são os cabeçalhos cobertos pela assinatura, e nada além: nunca a sua chave. A URL precisa ser HTTPS, a não ser no emulador local. O armazenamento confere o corpo contra o tamanho e o hash declarados. Com subject, o arquivo fica guardado sob aquela pessoa, então apagar a pessoa apaga o arquivo, mesmo que nenhum evento o cite.
Devolve um MediaUpload com media_ref, media_sha256, content_type, size_bytes e expires_at, ou None quando o upload falhou. Cada tentativa da transferência tem o tempo máximo upload, 60 s por padrão.
handoff()
Registra uma transferência para um humano ("human") ou para outro agente ("agent"). Vai para a fila. A medição do aproveitamento do contexto lê esse registro para contar transferências em que o destino não leu o contexto.
conversation()
Uma conversa com um cliente, usada como gerenciador de contexto. Sair do bloco emiteconversation.ended, mesmo quando o bloco levantou exceção.
conversation_id, o SDK cria um. channel vem do cliente quando não é passado. agent_id identifica o seu agente dentro da fonte e vai carimbado nos turnos e nas ações dele.
O primeiro
context() recebe o contexto que o servidor fixa para a conversa. As leituras seguintes pedem também o delta, e a conversa guarda cada delta que chega, em ordem, então turn_block leva todas as mudanças desde a fixação, seguidas dos turnos ao vivo. Quando o servidor fixa um contexto novo, depois de verify() por exemplo, os deltas guardados saem: o contexto novo já os contém. Uma leitura com query= é avulsa e não mexe neles.
Chame mark_injected() toda vez que puser o contexto num prompt. É assim que a Niadra distingue um contexto que chegou depois de o agente falar de um contexto que o agente tinha e não usou. A sessão guarda também context_injected_at e first_agent_turn_at, o primeiro de cada, para as suas próprias checagens.
current_session() devolve a conversa ou tarefa cujo bloco está rodando na thread ou task atual, se houver.
task()
O mesmo para um agente interno (cobrança, pedidos, tickets). Emitetask.ended na saída.
object, o contexto fica centrado nele; use uma view de tarefa como task:billing. Uma tarefa tem os mesmos métodos de uma conversa, menos handoff().
tools()
O kit do histórico como ferramentas de chamada de função, amarrado a um cliente. O cliente fica amarrado aqui, fora do alcance do modelo: o modelo escolhe a consulta, nunca o perfil, e é isso que impede uma injeção de prompt de trocar de cliente.AsyncNiadra.tools() devolve um AsyncToolKit, com call() aguardado. As definições também saem em GET /v1/history/tools.
subject_token()
Emite um token assinado, de 15 minutos, que amarra uma conexão MCP a um cliente. Chame do seu backend. Corresponde aPOST /v1/subject-tokens.
SubjectToken com token, expires_at e headers, o cabeçalho Niadra-Subject-Token que vai junto da chave da fonte quando o agente abre a conexão com mcp_url. Com about, a organização fica amarrada como o sujeito. Veja MCP com qualquer LLM.
wrap()
Embrulha o cliente Python da OpenAI, ou qualquer cliente com o mesmo formato, para toda chamada dentro de um bloco de conversa ou tarefa receber o contexto e registrar a resposta.chat.completions.create e chat.completions.parse, síncronos ou assíncronos, com streaming ou sem, recebem o contexto fixado como mensagem de sistema logo depois das suas mensagens de sistema iniciais, e o turn_block como mensagem de sistema no fim. A injeção é carimbada com mark_injected(), e a resposta do modelo é registrada como turno do agente: quando o stream termina ou é fechado e, por with_raw_response, quando você chama parse(). Fora de um bloco, as chamadas passam intactas. O embrulho devolve um proxy e nunca altera o seu cliente. Nada do que ele faz derruba a chamada ao modelo: um contexto que não chega fica de fora, e uma falha ao registrar a resposta vai para o log, sem conteúdo.
flush() e close()
flush() manda tudo o que está na fila a partir da thread que chamou e devolve True quando não sobra nada. close() esvazia a fila por até timeout segundos e libera as conexões. No AsyncNiadra, os dois são aguardados.
AsyncNiadra
AsyncNiadra tem os mesmos métodos. As leituras, identify(), verify(), feedback(), upload_media(), subject_token(), flush() e close() são aguardados; track(), action(), handoff(), conversation(), task() e tools() não. Conversas e tarefas são gerenciadores de contexto assíncronos.
Erros
Comstrict=True, ou nos ajudantes que você chama direto, como ApiKey.parse() e as funções de handle, o SDK levanta:
O catálogo completo de códigos está em Erros. Cite
request_id quando falar com o suporte.
Emulador local
niadra-mock, instalado junto da biblioteca, é um emulador local, em memória, da mesma API. Nos testes, rode o SDK contra ele no mesmo processo:
verify(), os objetos tiram o estado dos eventos de sistema, a correção vira um evento feedback.* e os uploads de mídia vão para mock.cell.media. mock.cell também deixa inspecionar eventos e provocar falhas (fail_next, revoke, cut, put_in_holdout). No terminal, niadra-mock --port 8765 serve o emulador por HTTP.
Próximos passos
SDK de TypeScript
A mesma superfície para Node e runtimes de borda.
Início rápido
Da chave ao primeiro contexto entregue.
O contexto e as views
O que entra no contexto e por quê.
Erros
O catálogo de códigos e o que fazer com cada um.

