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| import | o que ela contém |
|---|---|
@colliepwa/durable-sdk | openCollie 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/bun | A mesma API, sempre com o servidor do Bun |
@colliepwa/durable-sdk/node | A mesma API, sempre com o servidor node:http, mais NO_DESCENDANT_CHECK, a linha que ele grava na inicialização |
@colliepwa/durable-sdk/core | O 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/pi | A 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.
| runtime | a verificação de descendente | o que você define |
|---|---|---|
| Bun no Linux | Ativado por padrão. O Bun lê o ID de processo do chamador diretamente do socket | Nada. callerCheck: "off" desativa isso |
| Bun no macOS, ou qualquer outro sistema exceto Linux | Não pode executar. A inicialização falha com um erro que indica callerCheck | callerCheck: "off" |
| Node, qualquer sistema | Não pode executar: o Node não consegue ler quem chamou um socket. O agente durável escreve uma linha na inicialização informando isso | Nada. 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ção | o que faz | padrão |
|---|---|---|
socket | O 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 0700 | A variável COLLIE_DURABLE_SOCKET. Se nenhuma estiver definida: a inicialização falha |
hostName | O próprio nome do agente durável no seu hello, truncado para 64 bytes. Obrigatório | Nenhum |
tailLimit | Quantos eventos brutos cada painel mantém para as leituras do Collie | 500, no máximo 1000 |
caps | O que o agente durável informa que pode fazer (Caps) | Tudo o que o SDK pode fazer |
callerCheck | descendant ou off. Lido apenas no Bun | descendant |
hooks | Um local nomeado para cada ato enviado pelo telefone (Hooks e histórico) | Nenhum |
warn | Onde o SDK grava suas notas de uma linha, por exemplo sobre um Collie que fala outra versão de conexão | console.warn |
onRename | Obsoleto. O nome antigo de hooks.onRename, mantido por uma versão, sem o id da requisição | Nenhum |
Mais duas opções existem apenas em createCore, não em openCollie: receipts e allowAlways (Perguntas).
| no handle | o que é |
|---|---|
address | O caminho de socket em que ele escuta |
epoch | Novo e aleatório a cada inicialização, 128 bits |
core | O 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étodo | o que o telefone exibe | limite |
|---|---|---|
state(s) | working, waiting ou idle. Uma alteração em working inicia um novo turno | Enquanto qualquer ask estiver aberto, o painel exibe waiting |
event(e) | Itens do chat: eventos item, remove, settled, reset e synced | Veja a tabela de itens abaixo |
subtitle(text) | Uma linha sob o título. null a limpa | 120 caracteres |
badge(value) | { count } ou { text } ao lado do título. null o limpa | Uma 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 limpa | 12 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ões | 4 botões, um rótulo de 16 caracteres |
onAction(fn) | Executa um toque em um desses botões. Retorne false para recusá-lo | O 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, outcomeOf | Altere, decida ou leia de volta uma solicitação (Perguntas) | Nenhum |
close() | Remove o painel do layout. Suas solicitações abertas fecham como interrompidas | Nenhum |
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.
| tipo | o que ela contém | limite |
|---|---|---|
user | Uma linha que a pessoa enviou. requestId indica o envio de onde ela veio, para que o telefone troque sua própria linha por ela | 64 KiB de texto |
reply, thinking, notice | As palavras do agente | 64 KiB de texto |
markdown | Texto que o telefone renderiza como markdown: títulos, listas, ênfase, trechos de código e links | 32 KiB de texto |
code | Um bloco de código, com lang como ts | 32 KiB de texto. lang tem de 1 a 24 letras, dígitos ou _ + # . - |
link | Um href e um label opcional | href é apenas https://, no máximo 2048 caracteres. label tem 120 caracteres |
tool | Uma chamada de ferramenta: tool: { kind: "other", name, summary, output? } e um status de running, done, failed ou denied | name 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 requireApproval | o que faz | padrão |
|---|---|---|
pane | O painel que faz a solicitação. Obrigatório | Nenhum |
toolCallId | O próprio id da chamada de ferramenta, o mesmo após uma reinicialização. Qualquer string: uma que viole a regra de id é tornada segura | Obrigatório |
itemId | O item sob o qual o card fica | O id da chamada de ferramenta |
timeoutMs | Quanto tempo o telefone tem. Passado esse tempo a chamada é negada, decidida por timeout | Sem limite |
signal | Um AbortSignal. Abortar nega a chamada, decidido por program | Nenhum |
labels | O 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.
kind | o que o card mostra | a resposta | limite |
|---|---|---|---|
permission | Um botão por opção, cada um com um effect: allow, allow-always, deny ou cancel | { optionId, note? } | 1 a 6 opções |
choice | Um botão por opção. Com multiple: true a pessoa escolhe várias | { optionIds } | 1 a 8 opções |
text | Um campo de texto, com um placeholder opcional | { text } | maxLength de 1 a 2000, padrão 500. O placeholder tem 60 caracteres |
form | 1 a 6 campos, cada um do tipo text, choice ou toggle, alguns required | { values }, indexado pelo id do campo | Um 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 painel | o 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çãoallow-alwayspermite 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.createCorecomallowAlways: falsetorna uma opçãoallow-alwaysumTypeError. O telefone não ofereceallow-alwaysem 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.
| hook | quando executa | como recusa |
|---|---|---|
onSend(pane, { text, steer, turnId, requestId }) | Texto para um painel que não tem pane.onSend | Lança: 500 internal, um resultado desconhecido para o telefone |
onAbort(pane, { turnId, requestId }) | Parada para um painel que não tem pane.onAbort | Lança, como acima |
onAction(pane, { actionId, turnId?, requestId }) | Um toque na barra para um painel que não tem pane.onAction | Retorna false: 422 action-refused |
onRename({ kind, id, title }, requestId) | Um novo título para um workspace ou uma aba | Retorna false: 422 rename-refused |
onClose({ kind, id, paneIds }, requestId) | O telefone fecha um painel, uma aba ou um workspace | Retorna false: 422 close-refused |
onReopen({ id, paneId? }, requestId) | O telefone reabre uma conversa fechada | Retorna 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.
HistoryProvider | retornos |
|---|---|
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.
| limite | o que o agente durável aceita |
|---|---|
asks | Faz perguntas e recebe respostas |
starters | Lista starters e executa um a partir da página Novo |
send | Recebe texto do telefone |
steer | Recebe texto em um turno em andamento. Precisa de send |
abort | Interrompe um turno em execução |
rename | Recebe um novo título para um workspace ou uma aba |
close | Fecha um painel, uma aba ou um workspace |
actions | Lista os botões do cinto em um painel e executa um |
history | Disponibiliza suas conversas, abertas e fechadas |
reopen | Mostra 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.
| export | o 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) |
handle | O 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, versionLine | A 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 |
AskClosed | O 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, progressOf | Um destino de link, uma linguagem de código, um badge e um progresso, validados da mesma forma que o painel os valida |
subtitleOf, pushTextOf, renameTitleOf | Um subtítulo, as palavras de push de um ask e um título renomeado, limpos e cortados |
CAPS, LIMITS | Cada cap por campo em bytes e cada cap por lista |
ACTION_LABEL_MAX, BADGE_TEXT_MAX, BADGE_COUNT_MAX | 16, 12 e 9999 |
SUBTITLE_MAX, LINK_LABEL_MAX, RENAME_TITLE_MAX | 120 caracteres cada |
PROGRESS_STEPS_MAX, PROGRESS_LABEL_MAX | 12 etapas, 60 caracteres |
PUSH_TITLE_MAX, PUSH_LINE_MAX, PLACEHOLDER_MAX | 60, 120 e 60 caracteres |
ANSWER_TEXT_MAX, ANSWER_TEXT_DEFAULT, ANSWER_TEXT_BYTES | 2000 e 500 caracteres, e 8000 bytes |
ALL_CAPS, PROTOCOL_RANGE, SOCKET_ENV | Todas as caps ativadas, as versões de protocolo suportadas pelo SDK e o nome COLLIE_DURABLE_SOCKET |
MemoryReceiptStore, RECEIPTS_PER_GROUP | O 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.
| export | o 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 |
PaneRegistry | Qual 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 |
Mapper | Entradas do Pi e eventos do agente como itens. Uma resposta em andamento mantém um único id de item |
PARTIAL_MS, RE_RAISE_MS | 250 ms entre duas gravações de uma resposta em andamento e os 5000 ms que reRaised espera no máximo |
ESCALATED | Vocabulário de exemplo: o aviso do suporte para o botão Escalate que showConversation adiciona com escalate: true |
ASKING_TOOLS | Vocabulário de exemplo: os nomes das duas ferramentas de consulta do suporte |
Submit, ReplyExtras | Os 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.
| hoje | o que significa | |
|---|---|---|
SDK_VERSION | 0.1.0 | A versão do pacote. Até que o pacote deixe a dist-tag experimental, uma versão minor pode alterar a API |
WIRE_VERSION | 1 | A 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).