Pular para o conteúdo
ColliePWA

09/Documentation

O SDK de durable agent (experimental)

O pacote npm @colliepwa/durable-sdk, parte por parte: suas entradas e runtimes, openCollie, os métodos de painel, os quatro tipos de pergunta e requireApproval, hooks, histórico, caps, os auxiliares, a integração com o Pi e as versões

Experimental. O pacote, sua API e o protocolo que ele utiliza podem mudar, ou o recurso pode ser removido, em uma versão secundária posterior. Versões explica o que isso significa para o seu durable agent.

@colliepwa/durable-sdk é o pacote npm que um durable agent usa para aparecer no seu telefone pelo Collie. Esta página lista todas as suas partes. Durable agents contém o guia rápido e a configuração no Collie, e O durable wire explica o que trafega entre os dois.

Instalação e pontos de entrada

Uma instalação fornece cinco pontos de entrada: a importação raiz para a maioria dos durable agents e quatro para necessidades mais específicas.

npm install @colliepwa/durable-sdk@experimental
# or
bun add @colliepwa/durable-sdk@experimental
importo que ela contém
@colliepwa/durable-sdkopenCollie e toda a API. No Bun ele serve o socket com o servidor do Bun, em outros ambientes com o servidor node:http
@colliepwa/durable-sdk/bunA mesma API, sempre com o servidor do Bun
@colliepwa/durable-sdk/nodeA mesma API, sempre com o servidor node:http, mais NO_DESCENDANT_CHECK, a linha que ele grava na inicialização
@colliepwa/durable-sdk/coreO layout e a conexão em uma única função, handle(request), para um agente durável que traz seu próprio transporte. Sem importação em tempo de execução, então executa onde quer que um Request web execute
@colliepwa/durable-sdk/piA integração para um agente durável construído sobre o Pi Durable (Os utilitários do Pi)

O pacote precisa do Node 22.19 ou posterior, ou Bun 1.4 ou posterior, e não tem dependência de tempo de execução. ./pi precisa de @earendil-works/pi-durable, @earendil-works/pi-ai e @earendil-works/chord, 1.1 ou posterior e abaixo de 2. O ponto de entrada é testado com Pi Durable 1.1.0 e 1.2.0. Os três são peer dependencies opcionais: um agente durável que nunca importa ./pi não instala nenhum.

O runtime decide se o agente durável pode identificar quem responde. A verificação de descendente recusa uma ação vinda do próprio agente durável ou de um processo iniciado por ele, com 403 caller-refused. Ela cobre answer, send, stop, action, rename, close, reopen e starter. As leituras continuam abertas.

runtimea verificação de descendenteo que você define
Bun no LinuxAtivado por padrão. O Bun lê o ID de processo do chamador diretamente do socketNada. callerCheck: "off" desativa isso
Bun no macOS, ou qualquer outro sistema exceto LinuxNão pode executar. A inicialização falha com um erro que indica callerCheckcallerCheck: "off"
Node, qualquer sistemaNão pode executar: o Node não consegue ler quem chamou um socket. O agente durável escreve uma linha na inicialização informando issoNada. callerCheck não é lido

Sem a verificação, qualquer processo do seu usuário pode responder a um card, incluindo uma ferramenta executada pelo agente. Execute as ferramentas do agente em um sandbox que não consiga alcançar o socket. O socket precisa de um sistema com proprietários de arquivos, então no Windows openCollie é interrompido na inicialização. Em vez disso, um agente durável nesse sistema serve ./core sob TLS com um token (Duas formas de acessar um agente durável).

Abra uma conexão

openCollie cria o socket privado, e o identificador retornado define o layout exibido no telefone.

import { openCollie } from "@colliepwa/durable-sdk";

const collie = await openCollie({ hostName: "desk" });
const space = collie.workspace("support", { title: "Support" });
const tab = space.tab("main", { title: "Tickets" });
const pane = tab.pane("ticket-1", { title: "Maria Lopez", harness: "desk" });
collie.ready();

Sem a opção socket, o caminho vem de COLLIE_DURABLE_SOCKET, a mesma variável que o Collie lê.

opçãoo que fazpadrão
socketO caminho do socket: absoluto, no máximo 103 bytes. Sua pasta é criada com o modo 0700, ou já deve pertencer a você com o modo 0700A variável COLLIE_DURABLE_SOCKET. Se nenhuma estiver definida: a inicialização falha
hostNameO próprio nome do agente durável no seu hello, truncado para 64 bytes. ObrigatórioNenhum
tailLimitQuantos eventos brutos cada painel mantém para as leituras do Collie500, no máximo 1000
capsO que o agente durável informa que pode fazer (Caps)Tudo o que o SDK pode fazer
callerCheckdescendant ou off. Lido apenas no Bundescendant
hooksUm local nomeado para cada ato enviado pelo telefone (Hooks e histórico)Nenhum
warnOnde o SDK grava suas notas de uma linha, por exemplo sobre um Collie que fala outra versão de conexãoconsole.warn
onRenameObsoleto. O nome antigo de hooks.onRename, mantido por uma versão, sem o id da requisiçãoNenhum

Mais duas opções existem apenas em createCore, não em openCollie: receipts e allowAlways (Perguntas).

no handleo que é
addressO caminho de socket em que ele escuta
epochNovo e aleatório a cada inicialização, 128 bits
coreO núcleo por trás do socket. Um teste, ou um segundo transporte, chama core.handle diretamente
workspace(id, { title, cwd? })Um workspace, criado uma vez por id. Seu tab(id, { title }) gera uma aba, e o pane(id, options) da aba gera um painel
starters(list)O que o telefone pode iniciar a partir da página Novo, no máximo 50. Cada um é { id, label, run }, e run resolve para { paneId } do painel exibido
history(provider)Disponibilize o registro próprio do agente durável sobre suas conversas (Hooks e histórico)
ready()Chame quando todo painel for exibido, e após uma reinicialização quando todo ask aberto for gerado novamente. Até lá, toda rota exceto hello responde 503 starting
close()Pare o servidor. Respostas já em trânsito ainda saem, por no máximo 2 s, depois o arquivo de socket é removido

close() deixa asks abertos abertos de propósito: um encerramento não é uma resposta, e o agente durável decide o que acontece com o trabalho que espera por um.

tab.pane(id, { title, harness, cwd?, sessionId? }) retorna o painel que possui esse id quando ele existe, para que um agente durável possa exibir uma conversa duas vezes sem um segundo painel. Títulos são cortados em 256 bytes e harness em 64. cwd é um caminho absoluto, caso contrário é omitido.

Todo id segue a regra de id: 1 a 128 bytes, sem caracteres de controle, sem espaço em branco e nenhum de /, ? ou #. Um id inválido é um TypeError. Um id de workspace ou aba não pode conter :, porque a conexão nomeia uma aba como <workspace>:<tab>.

Painéis

Um painel é uma conversa, e seus métodos definem o que o telefone exibe para ela.

métodoo que o telefone exibelimite
state(s)working, waiting ou idle. Uma alteração em working inicia um novo turnoEnquanto qualquer ask estiver aberto, o painel exibe waiting
event(e)Itens do chat: eventos item, remove, settled, reset e syncedVeja a tabela de itens abaixo
subtitle(text)Uma linha sob o título. null a limpa120 caracteres
badge(value){ count } ou { text } ao lado do título. null o limpaUma contagem de 0 a 9999, um texto de 12 caracteres
progress(value){ kind: "steps", steps } ou { kind: "percent", value, label? }, renderizado enquanto o painel trabalha ou espera. null o limpa12 etapas, cada rótulo com 60 caracteres, um valor de 0 a 100
actions(list)Botões na seção do agente durável da esteira: { id, label, icon?, busy?, disabled? }. null limpa os botões4 botões, um rótulo de 16 caracteres
onAction(fn)Executa um toque em um desses botões. Retorne false para recusá-loO telefone não envia nenhum toque para um botão busy ou disabled
onSend(fn)Recebe o texto do telefone, como fn(text, { steer, requestId })32 KiB de texto
onAbort(fn)Recebe Stop, como fn({ requestId })Nenhum
ask(input, { signal? })Um cartão de pergunta (Perguntas)50 solicitações abertas por painel
updateAsk, decideAsk, outcomeOfAltere, decida ou leia de volta uma solicitação (Perguntas)Nenhum
close()Remove o painel do layout. Suas solicitações abertas fecham como interrompidasNenhum

Um painel também tem quatro campos somente leitura: id, sessionId, turnId (o turno em execução, ou o último) e openAsks. O icon de uma ação é um entre play, pause, check, x, refresh, archive, flag, star, send, note, search e more. Outro nome não desenha nenhum ícone.

Um evento item carrega um item com um id e um ts opcional. Um item com um id conhecido substitui o anterior no mesmo lugar.

tipoo que ela contémlimite
userUma linha que a pessoa enviou. requestId indica o envio de onde ela veio, para que o telefone troque sua própria linha por ela64 KiB de texto
reply, thinking, noticeAs palavras do agente64 KiB de texto
markdownTexto que o telefone renderiza como markdown: títulos, listas, ênfase, trechos de código e links32 KiB de texto
codeUm bloco de código, com lang como ts32 KiB de texto. lang tem de 1 a 24 letras, dígitos ou _ + # . -
linkUm href e um label opcionalhref é apenas https://, no máximo 2048 caracteres. label tem 120 caracteres
toolUma chamada de ferramenta: tool: { kind: "other", name, summary, output? } e um status de running, done, failed ou deniedname 128 bytes, summary 1 KiB, output 16 KiB

Um item reply, thinking, notice ou markdown pode carregar partial: true enquanto seu texto cresce. Escreva o mesmo id novamente conforme ele cresce, no máximo a cada 250 ms, e depois mais uma vez com o texto final e sem partial, antes que o painel saia de working.

O texto além do limite é cortado, e caracteres de controle e invisíveis são removidos. Um lang inválido, um href inválido, um badge inválido ou um progresso inválido vira um TypeError ou um RangeError, porque o Collie o descartaria. Um agente durável não pode anexar eventos ask, ask-closed ou state por conta própria: ask() e state() escrevem esses eventos.

Perguntas

pane.ask mostra um cartão e resolve com a resposta, e requireApproval pergunta sobre uma chamada de ferramenta em uma linha.

import { requireApproval } from "@colliepwa/durable-sdk";

const args = { order: "5521", amount: 40 };
const approval = await requireApproval("refund", args, {
  pane,
  toolCallId: "call-1",
  timeoutMs: 10 * 60_000,
});
if (!approval.approved) throw new Error(`refund not approved: ${approval.decidedBy}`);

requireApproval(toolName, args, options) constrói o cartão a partir do que a chamada é, nunca das palavras do modelo sobre ela. O título é "refund wants to run", a linha da ferramenta é refund(order: "5521", amount: 40), a notificação diz "refund needs a yes", e os botões são Allow e Deny. Retorna { approved, decidedBy, decidedAt, askId }. Uma negação, um tempo limite esgotado, uma parada e um cancelamento retornam approved: false.

opção de requireApprovalo que fazpadrão
paneO painel que faz a solicitação. ObrigatórioNenhum
toolCallIdO próprio id da chamada de ferramenta, o mesmo após uma reinicialização. Qualquer string: uma que viole a regra de id é tornada seguraObrigatório
itemIdO item sob o qual o card ficaO id da chamada de ferramenta
timeoutMsQuanto tempo o telefone tem. Passado esse tempo a chamada é negada, decidida por timeoutSem limite
signalUm AbortSignal. Abortar nega a chamada, decidido por programNenhum
labelsO texto dos dois botões, { allow?, deny? }Allow e Deny

callSummary(name, args) e argumentsView(args) são as duas partes que ele usa: a chamada em uma linha, e os argumentos como pares key: value com cada valor como JSON.

pane.ask(input) aceita um de quatro tipos. A promise é resolvida com a resposta no formato do tipo.

kindo que o card mostraa respostalimite
permissionUm botão por opção, cada um com um effect: allow, allow-always, deny ou cancel{ optionId, note? }1 a 6 opções
choiceUm botão por opção. Com multiple: true a pessoa escolhe várias{ optionIds }1 a 8 opções
textUm campo de texto, com um placeholder opcional{ text }maxLength de 1 a 2000, padrão 500. O placeholder tem 60 caracteres
form1 a 6 campos, cada um do tipo text, choice ou toggle, alguns required{ values }, indexado pelo id do campoUm campo de escolha tem de 1 a 8 opções

Cada tipo aceita toolCallId, itemId e title (256 bytes). Pode aceitar reason (2 KiB), tool, push: { title?, line? } (60 e 120 caracteres, o texto da notificação) e expiresAt (um Date ou uma string ISO 8601 com fuso).

Deixe id de fora. O SDK deriva isso com askIdFor(paneId, toolCallId): SHA-256 sobre os dois ids, os primeiros 32 caracteres hexadecimais. A mesma chamada de ferramenta feita novamente após uma reinicialização recebe, portanto, o mesmo id, e uma resposta que o telefone enviou durante a reinicialização é entregue. Fazer uma chamada com um id que já está aberto gera um TypeError.

no painelo que faz
updateAsk(askId, patch)Altera um ask aberto no local: title, reason, tool, options, placeholder, maxLength ou fields. Sua revisão aumenta em um, portanto uma resposta ao formulário antigo recebe 409 stale e o telefone solicita um novo toque. Falso quando o ask não está aberto
decideAsk(askId, answer?)O agente durável decidiu o ask por conta própria, em outro lugar que não o telefone. Com answer, o ask() em espera resolve com ele. Sem isso, rejeita com AskClosed. Um toque posterior no telefone recebe 409 decided, e o card diz "Decided in the durable agent." Falso quando o ask não está aberto
outcomeOf(askId)A primeira decisão: { decidedBy, decidedAt, optionId?, effect? }. O painel lembra dos seus últimos 500. Indefinido para um ask que ele nunca fez ou esqueceu

decidedBy é phone, program ou timeout. Um ask passa do seu expiresAt e fecha como decidido por timeout: ask() rejeita com AskClosed, cujo decidedBy é timeout. O card mostra o tempo restante até lá. Uma pergunta que expirou ou foi decidida no agente durável deixa uma linha no Chat, como "Timed out before an answer: refund wants to run".

Um signal abortado, pane.close() e um fechamento a partir do telefone fecham o ask como decidido por program, e ask() rejeita com AskClosed.

Atenção. Uma opção allow-always permite todas as chamadas posteriores após uma resposta. Via https o token é a única barreira, portanto um agente durável nesse caso oferece apenas Allow e Deny. createCore com allowAlways: false torna uma opção allow-always um TypeError. O telefone não oferece allow-always em um ask cujo texto foi cortado ou limpo, ou que não nomeia ferramenta alguma.

Toda ação vinda do telefone traz um id de requisição, e o núcleo guarda seu recibo: uma repetição não executa nada e recebe a primeira resposta novamente com replayed: true. O MemoryReceiptStore padrão mantém os RECEIPTS_PER_GROUP mais recentes (1000) por painel, e por grupo para starters, renomeações, fechamentos e reaberturas. A repetição de um id descartado recebe 500 receipt-dropped e não executa nada. O armazenamento desaparece junto com o processo.

Para manter os recibos através de uma reinicialização, escreva um ReceiptStore com get(requestId) e put(requestId, record, group), e passe-o para createCore como receipts. O openCollie sempre os mantém na memória.

Hooks e histórico

Um hook é o local nomeado único para uma ação enviada pelo telefone, e um provedor de histórico serve seu próprio registro.

hookquando executacomo recusa
onSend(pane, { text, steer, turnId, requestId })Texto para um painel que não tem pane.onSendLança: 500 internal, um resultado desconhecido para o telefone
onAbort(pane, { turnId, requestId })Parada para um painel que não tem pane.onAbortLança, como acima
onAction(pane, { actionId, turnId?, requestId })Um toque na barra para um painel que não tem pane.onActionRetorna false: 422 action-refused
onRename({ kind, id, title }, requestId)Um novo título para um workspace ou uma abaRetorna false: 422 rename-refused
onClose({ kind, id, paneIds }, requestId)O telefone fecha um painel, uma aba ou um workspaceRetorna false: 422 close-refused
onReopen({ id, paneId? }, requestId)O telefone reabre uma conversa fechadaRetorna false: 422 reopen-refused

Um hook executa apenas quando sua cap está ativa e seu id de requisição é novo. Uma recusa não armazena nada, permitindo que o mesmo id de requisição tente novamente. Os handlers por painel têm precedência sobre um hook. Um painel sem nenhum dos dois responde 409 not-supported a um envio, parada ou toque.

O próprio SDK aplica uma ação aceita. Uma renomeação define o título. Um fechamento remove o destino e tudo dentro dele, e fecha suas solicitações em aberto como interrompidas. Uma reabertura sem um hook restaura um painel fechado por este processo; uma conversa fechada antes de uma reinicialização precisa de onReopen. O layout é recriado a cada inicialização, portanto um agente durável que deseja manter um título ou um fechamento além do processo deve salvá-lo em seu hook.

collie.history(provider) serve todas as conversas, abertas e fechadas, a partir do próprio armazenamento do agente durável. Ele ativa a cap history quando caps é omitido ou aponta para history: true.

HistoryProviderretornos
list(after, limit){ items, next? }: linhas de conversa, da mais recente para a mais antiga, no máximo limit (100)
items(id, after, limit){ items, next? }: os itens da conversa, do mais antigo para o mais recente, cada um em sua versão mais recente, no máximo limit (1000). undefined para um id desconhecido

Uma linha é { id, title, subtitle?, workspaceId?, tabId?, startedAt, endedAt?, state, items }, com state open ou closed e items a contagem. Um cursor (after, next) é sua própria string, de 1 a 512 bytes de ASCII imprimível sem espaços. A ausência de next encerra a lista.

Após definir um provedor, o sessionId de cada painel passa a ser seu id de painel, e o histórico serve a conversa do painel sob ele. Passe sessionId para tab.pane() para especificar outro id, ou null quando ele não puder permanecer o mesmo após uma reinicialização.

tailLimit não é histórico. É a cauda bruta que cada painel mantém para as leituras de eventos do Collie, por padrão 500 eventos. Um leitor que ficou para trás recebe a visualização atual inteira do painel, no máximo os 2000 itens mais recentes.

Caps

Uma cap indica que o agente durável pode realizar uma ação, e o telefone renderiza um controle apenas para uma cap declarada pelo agente durável.

limiteo que o agente durável aceita
asksFaz perguntas e recebe respostas
startersLista starters e executa um a partir da página Novo
sendRecebe texto do telefone
steerRecebe texto em um turno em andamento. Precisa de send
abortInterrompe um turno em execução
renameRecebe um novo título para um workspace ou uma aba
closeFecha um painel, uma aba ou um workspace
actionsLista os botões do cinto em um painel e executa um
historyDisponibiliza suas conversas, abertas e fechadas
reopenMostra novamente uma conversa fechada

Omitido, caps ativa tudo o que o SDK pode fazer, e history assim que history() tiver um provedor. Informado, representa a lista inteira: uma cap não mencionada fica desativada, portanto { asks: true } declara apenas asks. Para desativar uma e manter o restante, espalhe ALL_CAPS: { ...ALL_CAPS, steer: false }. Uma rota cuja cap está desativada responde 409 not-supported. terminal é sempre false.

Utilitários e constantes

A importação raiz também exporta as partes que compõem openCollie e as regras que ele aplica.

exporto que é
createCore(options)O núcleo sem um servidor. Aceita as opções de openCollie, exceto socket e callerCheck, mais receipts e allowAlways. Retorna epoch, workspace, starters, history, ready, isReady e handle(request)
handleO protocolo como uma única função, recebendo um Request web e retornando um Response. core.handle(request) é a forma de entrada habitual
wireListener(core)core.handle como um listener de requisições node:http, com drained() para um encerramento limpo
hello, versionLineA resposta de hello e a única linha que um agente durável grava para recusa de versão
mintId()Um novo id aleatório, 128 bits em 32 caracteres hexadecimais
askIdFor(paneId, toolCallId)O id de ask derivado
AskClosedO erro com o qual ask() rejeita quando nenhuma resposta chega. Contém by e decidedBy
idOk(id), assertId(id, what), safeId(raw)A regra de id: uma verificação, uma verificação que lança exceção e um id seguro gerado a partir de qualquer string, sempre o mesmo
cursorOk(cursor)A regra do cursor de histórico
cut(text, max, multiline?)Limpe uma string e corte-a para max bytes, com … no final
hrefOf, langOf, badgeOf, progressOfUm destino de link, uma linguagem de código, um badge e um progresso, validados da mesma forma que o painel os valida
subtitleOf, pushTextOf, renameTitleOfUm subtítulo, as palavras de push de um ask e um título renomeado, limpos e cortados
CAPS, LIMITSCada cap por campo em bytes e cada cap por lista
ACTION_LABEL_MAX, BADGE_TEXT_MAX, BADGE_COUNT_MAX16, 12 e 9999
SUBTITLE_MAX, LINK_LABEL_MAX, RENAME_TITLE_MAX120 caracteres cada
PROGRESS_STEPS_MAX, PROGRESS_LABEL_MAX12 etapas, 60 caracteres
PUSH_TITLE_MAX, PUSH_LINE_MAX, PLACEHOLDER_MAX60, 120 e 60 caracteres
ANSWER_TEXT_MAX, ANSWER_TEXT_DEFAULT, ANSWER_TEXT_BYTES2000 e 500 caracteres, e 8000 bytes
ALL_CAPS, PROTOCOL_RANGE, SOCKET_ENVTodas as caps ativadas, as versões de protocolo suportadas pelo SDK e o nome COLLIE_DURABLE_SOCKET
MemoryReceiptStore, RECEIPTS_PER_GROUPO armazenamento padrão de recibos e seu limite de 1000 por grupo

Todos os tipos transmitidos e todos os payloads de hooks também são exportados a partir de src/core/types.ts.

Os utilitários do Pi

./pi transforma uma conversa do Pi Durable em um painel, uma chamada de ferramenta arriscada em um card e o armazenamento do Pi em histórico.

exporto que faz
showConversation(loc, harness, conversation, o)Mostra uma conversa como um painel, primeiro o histórico e depois os eventos em tempo real. Send vai para o submit do Pi com o id da requisição, e Stop para seu abort. É seguro chamar duas vezes
PaneRegistryQual painel mostra qual conversa. Após reiniciar, reRaised(risky) espera até que cada chamada arriscada sem resultado pergunte novamente, portanto ready() vem depois das perguntas
riskGuard({ panes, risky, words?, timeoutMs?, onTimeout? })Uma extensão do Pi cujo hook beforeTool transforma uma chamada para uma ferramenta em risky em um card com Allow e Deny. Uma chamada negada é bloqueada. Com timeoutMs, o card expira, uma chamada que ninguém respondeu é bloqueada e onTimeout(tool, title) permite que o agente durável registre o evento
askTools({ panes, words, timeoutMs?, onTimeout? })As duas ferramentas de consulta do suporte: ask_queue, uma escolha, e ask_customer, uma pergunta em texto. Com timeoutMs, uma pergunta sem resposta expira e a ferramenta retorna "timed out"
spawnHelperTool(o)A ferramenta spawn_helper: uma conversa filha exibida como um novo painel, que retorna a resposta do assistente
piHistory({ harness, panes, describe })Um HistoryProvider que lê todas as entradas de todas as conversas do Pi
firstMessageOf(conversation)O texto da primeira mensagem de uma conversa, para nomear seu painel
paneIdOf(id), conversationOfPaneId(paneId)O id do painel de uma conversa do Pi, conv-<id>, e de volta
summaryOf(args, name?)Os argumentos de uma chamada de ferramenta em palavras, no máximo 200 caracteres
MapperEntradas do Pi e eventos do agente como itens. Uma resposta em andamento mantém um único id de item
PARTIAL_MS, RE_RAISE_MS250 ms entre duas gravações de uma resposta em andamento e os 5000 ms que reRaised espera no máximo
ESCALATEDVocabulário de exemplo: o aviso do suporte para o botão Escalate que showConversation adiciona com escalate: true
ASKING_TOOLSVocabulário de exemplo: os nomes das duas ferramentas de consulta do suporte
Submit, ReplyExtrasOs tipos de um submit personalizado e dos itens que um agente durável adiciona sob uma resposta concluída

As palavras exibidas em um card chegam como opções, portanto ./pi não contém nenhum texto do exemplo além dessas duas constantes. Foi escrito para o Pi Durable 1.1.0. O suporte em examples/durable-member/ junta todas as partes.

Versões

O pacote tem sua própria versão, separada da versão do Collie, e indica a versão do protocolo de comunicação que utiliza.

hojeo que significa
SDK_VERSION0.1.0A versão do pacote. Até que o pacote deixe a dist-tag experimental, uma versão minor pode alterar a API
WIRE_VERSION1A versão do protocolo durável que o pacote utiliza

O Collie utiliza uma versão do protocolo e aceita a anterior por uma versão minor após o lançamento de uma nova. Quando um Collie não aceita nenhuma das suas versões, o núcleo grava uma linha através de warn, uma vez por versão, por exemplo collie: Collie speaks wire v2, this durable agent speaks v1. Update the agent's SDK, or Collie. O telefone indica a incompatibilidade na página inicial do agente durável, nas palavras do próprio Collie. Atualize o lado mais antigo.

O pacote é publicado sob a dist-tag experimental do npm, nunca latest. Se o protocolo durável for para a saída, o pacote será descontinuado (ADR 0105).

Editar esta página no GitHub

The rest of the documentation