Ir para o conteúdo

38 · Licenças, uso offline e o que precisa da rede

Idiomas

O seletor lê turnos escritos em inglês e em português do Brasil (pt-BR). O idioma é escolhido, nunca adivinhado a partir do turno: na página Settings do console (Language the selector reads), em language numa requisição de plano, ou no settings.language do seu arquivo de vocabulário; sem nenhum deles, inglês. Um turno em português pode ser digitado com os acentos ou sem eles. O português europeu não é uma gramática que o seletor tenha, e um turno em qualquer outra língua não é lido.

O pacote stalwart-agents traz o runtime da Stalwart, compilado: o leitor que transforma cada turno num plano, a verificação de ferramentas, as verificações de resposta, a recuperação de passagens, as verificações de código, a licença e os medidores. Ele roda no seu processo, na sua máquina. Uma licença é o que o deixa rodar ali: esta máquina, ativada uma vez na sua conta. Este capítulo é o que roda na máquina e o que precisa do nosso serviço, como uma licença é ativada, mantida e liberada, e o que acontece quando ela expira.

O que roda onde

Onde o runtime está instalado, um turno e uma chamada de ferramenta não precisam de rede: o runtime responde aos dois na máquina que executa o seu agente.

O que acontece uma vez, antes da implantação ou em segundo plano pode usar o nosso serviço. Cada linha está ligada ao código que faz o trabalho, a operação do runtime ou a rota do serviço, e é gerada a partir dele:

Trabalho Onde roda Rede
ler um turno num plano o runtime, no seu processo nenhuma
verificar uma chamada de ferramenta: o catálogo, os argumentos, o histórico, as regras de ordem, o portão do rulebook, as marcas, os tokens de confirmação o runtime, no seu processo nenhuma
conferir uma resposta com o que foi feito, e examinar turnos e respostas em busca de dados pessoais o runtime, no seu processo nenhuma
indexar os seus documentos, recuperar passagens e conferir uma resposta com elas o runtime, no seu processo nenhuma; compose chama o seu próprio modelo, com a sua chave
as verificações de código do stalwart verify o runtime, no seu processo nenhuma
o lint de um catálogo o runtime, no seu processo nenhuma
a etapa de ferramenta protegida, desfazer uma execução que falhou, o retrocesso, as pausas por uma pessoa e a retomada o pacote, sobre o runtime, no seu processo nenhuma, exceto as chamadas que as suas próprias ferramentas fazem
as verificações do gateway o pacote, sobre o runtime, no seu processo nenhuma, exceto as chamadas que ele repassa aos seus servidores de ferramentas
um cálculo: o seu modelo escreve a função e a imagem do sandbox a executa, na sua máquina o pacote, sobre o runtime, no seu processo a chamada ao seu modelo; a função em si roda sem rede
compilar um rulebook Colang ou uma planilha de regras no registro que a verificação de ferramentas lê; nada é guardado o nosso serviço uma vez, quando um agente ou o stalwart verify lê as suas regras; nenhuma para uma pasta que o stalwart rules compile escreveu
a caça e a prova do grafo de um agente o nosso serviço antes da implantação: no stalwart verify, e uma vez por grafo antes do primeiro turno de um agente
ativar a licença e renovar a concessão o nosso serviço uma vez na ativação, depois em segundo plano; o runtime segue rodando durante o período de carência sem ela
relatar o uso: só contagens o nosso serviço em segundo plano, com a renovação da concessão
os pacotes que o runtime lê: o vocabulário, as regras de resposta e as frases o nosso serviço em segundo plano; um pacote novo é adotado numa renovação da concessão, nunca no meio de uma conversa
os polegares dos seus usuários, para o minerador o nosso serviço só quando você os envia

Ativando

$ export QLS_API_KEY=qls_live_...
$ stalwart licence activate        # uma vez em cada máquina
$ stalwart licence status          # a licença, a concessão, a carência e o que resta de cada limite
$ stalwart licence release         # libera o lugar desta máquina, para outra ocupar

A ativação cria a instalação desta máquina -- um id aleatório e um par de chaves, nunca uma impressão digital do hardware -- e troca a sua chave pela licença da sua organização e uma primeira concessão: a permissão do runtime para rodar aqui até uma data. O seu plano define quantas máquinas podem ter uma concessão ao mesmo tempo, quanto tempo dura uma concessão, o período de carência depois dela, e se uma máquina pode ser ativada sem nenhuma conexão:

A licença do runtime local Gratuito Pago Enterprise
installations: máquinas com uma concessão ao mesmo tempo 1 5 50
lease_days: dias que uma concessão dura antes de ser renovada 7 7 7
offline_grace_days: dias que o runtime continua funcionando além da concessão sem nos alcançar 7 30 30
offline_activation: ativar uma máquina que nunca alcança a rede, por arquivo de pedido não não sim

Nada no pacote funciona sem uma chave e uma licença ativada, exceto ativá-la, stalwart doctor e stalwart check. Sem elas, um comando para com LicenceRequired, nomeando stalwart licence activate.

Por HTTP, ativar é POST /v1/licences/activate. GET /v1/licences lê a licença e quantas instalações ocupam os seus lugares, e GET /v1/licences/keys, que não precisa de chave, lista as chaves públicas Ed25519 com que licenças e concessões são assinadas: uma versão do runtime as traz compiladas e não confia em nenhuma outra.

Executar no meu computador, a partir do console

Um bot montado no console roda num computador sem trabalho de terminal além de uma linha. Executar no meu computador, na página do bot, pede um tíquete que dura sete dias e pode ser gasto quantas vezes a linha for rodada, até um mais novo ser feito para o bot, e mostra a linha para Windows ou para Mac. A linha busca o instalador, GET /v1/install/{ticket}/{system}, que coloca o stalwart-agents num ambiente só dele, com um uv fixado. Depois o instalador gasta o tíquete, POST /v1/install/{ticket}, que responde com a definição do bot, uma chave criada para ele naquele momento e com o nome dele, e o endereço de email da pessoa, que as requisições ao Unpaywall levam. Rodar o bot de novo em outro computador revoga a chave que a execução anterior criou: um bot roda no computador que o rodou por último.

O instalador grava o bot como agent.yaml, com cada ferramenta que um servidor do pacote serve rodada por esse servidor no computador (capítulo 48), guardando os arquivos dela em Documents/Stalwart/ com o nome do bot. Ele ativa o computador como stalwart licence activate faz, inicia o stalwart serve --follows ao entrar no sistema (uma Tarefa Agendada no Windows, um agente do launchd no Mac) e abre o chat em http://127.0.0.1:8700/.

O script de remoção tira o bot do computador de novo: GET /v1/install/remove/{system}, windows para um script PowerShell e mac para um script de shell. Ele para o bot e o seu início no logon, devolve a vaga de licença do computador e apaga o que o instalador pôs ali, mantendo os arquivos do próprio bot em Documents/Stalwart/. Ele não precisa de chave nem de ticket: não nomeia ninguém.

O bot acompanha o console

O POST /v1/install/{ticket} também diz qual é o bot e a versão atual dele, que o instalador guarda em saved.json, ao lado do agent.yaml. Com --follows, o bot lê o pacote bot a cada quinze minutos: o bot como o console o salva agora, selado sob a concessão como todo pacote, e entregue só à chave que o instalador dele criou, com a versão mais nova do stalwart-agents publicada.

  • Uma versão mais nova que não retira nada -- ferramentas novas, tarefas novas, configurações alteradas -- é gravada como o agent.yaml do bot, como o instalador a gravaria, e o bot para com o código de saída 75; o script de execução o inicia de novo na nova versão. As execuções dele, guardadas no armazenamento dele, seguem.
  • Uma versão mais nova que retira alguma coisa -- um agente, uma ferramenta, uma tarefa ou um gatilho que ela não tem mais, ou as execuções guardadas em outro lugar -- espera em held.json. A página do chat diz o que ela retira, e Usar a nova versão a aplica (POST /updates/apply, com o cabeçalho Stalwart-Apply: yes, que uma página de outro site não consegue enviar).
  • Uma versão mais nova do stalwart-agents é avisada na página do chat; clicar de novo em Executar no meu computador a instala.

O GET /updates responde o que a página do chat mostra: {"held": {"version", "takes_away"} ou null, "software": {"installed", "newest"} ou null}.

A concessão, a sua renovação e o período de carência

A primeira resposta que o runtime dá num processo renova a concessão com o nosso serviço, de modo que um plano cancelado ou uma licença revogada param o runtime na hora; a mesma renovação busca o pacote de vocabulário e os outros, e relata as contagens. Quando o serviço não pode ser alcançado, o runtime abre a última concessão como ela está: dentro do prazo dela, e depois dentro do período de carência, ele responde normalmente, e stalwart doctor e stalwart licence status mostram o estado, active ou grace, e as datas em que a concessão e a carência terminam.

A renovação é POST /v1/licences/refresh. Cada pacote de dados vem de GET /v1/bundles/{kind} -- vocabulary, prompt_pack, reply_rules, outcome_phrasings, own_identifiers, language ou bot --, assinado, cifrado para a chave de pacotes da sua licença, e nomeado pelo digest do seu conteúdo, que toda decisão tomada com ele registra. own_identifiers é a lista que as Configurações do seu console guardam como os identificadores próprios da sua organização: o SDK e o stalwart procuram por eles em todo pedido destinado ao nosso serviço, além dos dados pessoais, e não enviam nada que contenha um deles. language traz as palavras com que o leitor lê cada mensagem, em cada idioma que lê: o runtime não planeja nenhuma mensagem até tê-las, e só aceita as palavras da sua própria versão. Mais um tipo é lido no seu próprio ritmo, e não na renovação: bot, o bot como o console o salva, a cada quinze minutos, para um bot que o acompanha (abaixo).

Rodando offline

O agente da loja do capítulo 30. Ele inicia com a rede, que prova o seu grafo e compila o seu rulebook:

desk = Agent.from_file("agent.yaml")
desk.chat("mostre o pedido 4412", user="u-0")    # a partida, com rede: a prova e o registro

Depois a rede é cortada, com todo socket recusado, e o agente segue:

# A rede é cortada aqui: daqui em diante nada sai da máquina.
reply = desk.chat("mostre o pedido 4411", user="u-17")
print(reply.text)
reply = desk.chat("cobre 40,00 do pedido 4411", user="u-17")
print(reply.waiting[0].tool, "waits:", reply.waiting[0].wording)
reply = desk.confirm("u-17", "approve")
print(reply.text)
card: visa-0019
customer: c-208
order_id: 4411
status: unpaid
total: 40.00
charge_card waits: Executar charge_card?
amount: 40
charge_id: ch-4411
order_id: 4411

A leitura foi respondida, a cobrança verificada e perguntada, e a cobrança aprovada executada, sem que nada saísse da máquina além da chamada à própria ferramenta da loja.

Quando a licença expira

Uma concessão e a sua carência já vencidas, ou a licença expirada, é uma licença expirada. Um produto de segurança não pode falhar aberto, e um agente em produção não pode parar sem aviso, então uma expiração degrada conforme a configuração on_licence_lapse da sua organização:

  • reads_only, o padrão: os turnos são lidos normalmente, as leituras são verificadas normalmente, e toda escrita é recusada como licence_lapsed.
  • refuse: toda operação é recusada como licence_lapsed, com a data em que a expiração começou.

O mesmo agente, depois que a licença dele expirou:

# A licença expirou, e a configuração da organização é `reads_only`.
reply = desk.chat("mostre o pedido 4411", user="u-18")
print(reply.text)
reply = desk.chat("cobre 40,00 do pedido 4411", user="u-18")
print(reply.text)
card: visa-0019
customer: c-208
order_id: 4411
status: unpaid
total: 40.00
A licença deste agente expirou, então charge_card não foi executada.

Nada que um runtime licenciado teria recusado é permitido durante uma expiração.

Máquinas sem conexão

Onde o seu plano permite a ativação offline, uma máquina que nunca alcança a Stalwart é ativada por arquivo, através de uma que alcança:

$ stalwart licence request                          # na máquina a ativar: escreve activation-request.json
$ stalwart licence answer activation-request.json   # numa máquina que alcança a Stalwart: escreve activation-answer.json
$ stalwart licence install activation-answer.json   # de volta na primeira máquina

A resposta traz a licença e uma concessão para todo o prazo da licença. Uma empresa pode, em vez disso, rodar o qls-licence-server na própria rede, que emite concessões para as suas máquinas como o serviço de licenças faz.

stalwart licence answer envia o pedido a POST /v1/licences/offline, que só responde para uma licença que permite ativação offline.

Liberando um lugar

stalwart licence release libera o lugar desta máquina na licença, para que outra máquina possa ocupá-lo: o que um job de CI faz por último (capítulo 46).

Por HTTP, é POST /v1/licences/release.

O que é contado, e o que é relatado

O runtime conta cada medidor que o seu plano nomeia -- plan_calls, tool_checks, answer_calls e as contagens das verificações de resposta, entre eles -- no seu próprio estado, no seu próprio relógio. Passado um limite, ele responde quota_exhausted, nomeando o medidor, como o serviço faz. Contagens, e só contagens, são relatadas: nunca um turno, um argumento, um resultado, uma resposta ou um documento. Os limites do seu plano estão no capítulo 16.

Elas vão para POST /v1/usage-reports como um registro assinado, contado como a diferença do último relatório da instalação, de modo que um relatório enviado duas vezes conta uma vez, e um arquivo de contadores voltado para trás é detectado.

stalwart doctor e stalwart licence

  • stalwart doctor imprime a URL base, se uma chave está configurada (nunca a chave), se o runtime local responde os planos e as verificações de ferramentas, com o estado da licença, a ida e volta até o serviço, o seu nível, os seus direitos e o uso de cada medidor neste mês, e se o streaming chega até você pela sua rede. Ele funciona sem licença, para dizer o que falta.
  • stalwart licence aceita activate, request, answer, install, release e status.

O que stalwart doctor imprime do seu plano é GET /v1/account, client.account() em Python: o plano da chave, as suas permissões e limites, e o uso de cada medidor neste mês. Qualquer chave pode lê-lo.

Os limites

  • Código compilado e pacotes cifrados dificultam a leitura; não a impedem. Alguém determinado, com uma instalação licenciada, pode extrair o que ela roda. Os termos da licença e o seu contrato são o que impede isso.
  • Alguns trabalhos ainda precisam do nosso serviço: a caça e a prova do grafo de um agente, a compilação do seu rulebook, a ativação e a renovação de uma licença, e o minerador. O primeiro início de um agente prova o seu grafo e compila o seu rulebook ali; uma máquina que nunca alcança o serviço roda só com a sua concessão e a carência.
  • Onde o runtime não está instalado -- uma plataforma para a qual o wheel não é distribuído -- nada responde aos planos nem às verificações de ferramentas, e a nossa API hospedada também não: rode os seus agentes numa plataforma para a qual o wheel é distribuído.