Saltar al contenido
ColliePWA

10/Documentation

El protocolo durable (experimental)

Qué viaja entre Collie y un durable agent, para desarrolladores: rutas, hello y la época, el ciclo de vida de un ask y los identificadores de solicitud, transportes por socket y token, límites y regla de versiones, con un enlace a WIRE.md para consultar las reglas exactas

Experimental. El cable puede cambiar, o la función puede eliminarse, en una versión menor posterior. Versiones y el saludo descriptivo describe cómo se transmiten los cambios.

El cable duradero es el medio con el que Collie se comunica con un agente duradero. Esta página lo explica para desarrolladores que creen un agente duradero sin el SDK o deseen saber qué hace el SDK. Las reglas exactas se encuentran en WIRE.md, y si esta página difiere de ese archivo, WIRE.md es el correcto. El SDK durable gestiona todo esto por usted.

Lo que se transmite

Collie llama y el agente persistente escucha, y cada intercambio es una solicitud HTTP con un cuerpo JSON.

El agente persistente escucha en un socket Unix privado o tras TLS en una URL (Transportes). Collie sondea: no hay push, ni WebSocket ni stream. Cada ruta empieza por /session/v1, que es un nombre fijo, no la versión. Cada llamada salvo la primera hello incluye la versión en la cabecera X-Collie-Session. El cuerpo de una solicitud es un único objeto JSON de 64 KiB como máximo, y un cuerpo POST vacío se interpreta como {}.

método y rutaqué hacelímite de respuesta
GET /helloNombre del agente persistente, rango de versiones, epoch, estado de preparación y caps16 KiB
GET /snapshotLa disposición: espacios de trabajo, pestañas, paneles con su estado, turno y asks abiertos, y starters. Incluye un ETag y responde 304 cuando no hay cambios4 MiB
GET /pane/:id/events?after=N&epoch=EEventos del panel tras un cursor8 MiB
POST /pane/:id/answerRespuesta a una ask16 KiB
POST /pane/:id/sendTexto para el panel, para dirigir el turno en ejecución o esperar al siguiente16 KiB
POST /pane/:id/abortDetener el turno en ejecución16 KiB
POST /pane/:id/actionPulsación en uno de los botones de la barra del panel16 KiB
POST /renameUn nuevo título para un espacio de trabajo o una pestaña16 KiB
POST /closeCerrar un panel, una pestaña o un espacio de trabajo16 KiB
POST /starter/:idEjecutar un starter. La respuesta nombra el nuevo panel16 KiB
GET /conversations?after=C&limit=NConversaciones del agente persistente, abiertas y cerradas, primero las más recientes1 MiB
GET /conversation/:id/items?after=C&limit=NElementos de una conversación, primero los más antiguos8 MiB
POST /reopenMostrar de nuevo una conversación cerrada16 KiB

Cada error es un cuerpo JSON con un code, como 409 stale o 404 no-such-pane. Cualquier otra ruta responde 404 not-found. Una respuesta que supere su límite no se lee, y un POST cuya respuesta quede cortada tiene un resultado desconocido (Identificadores de solicitud).

Hello y epoch

hello indica quién es el agente persistente y el epoch indica a qué inicio del mismo se dirige Collie.

campo de hellocontenido
serviceExactamente collie-durable. Sin él, Collie interpreta el agente persistente como otro servidor y no realiza más llamadas
protocolEl rango de versiones de protocolo que admite el agente persistente, { min, max }. Actualmente { min: 1, max: 1 }
host.nameNombre propio del agente persistente, solo texto visible, 64 bytes como máximo
epochNuevo y aleatorio en cada inicio del agente persistente, de al menos 128 bits, nunca reutilizado
readyFalse mientras el agente duradero organiza sus paneles tras un inicio
capsLo que el agente duradero puede hacer, cada uno como booleano. Una capacidad ausente es false

Collie llama primero a hello sin la cabecera de versión, elige la versión más alta que ambos lados admiten y la envía en cada llamada posterior. Mientras ready sea false, cada ruta excepto hello responde 503 starting, y el teléfono muestra el agente duradero como iniciándose. Un agente duradero establece ready solo cuando cada conversación se vuelve a mostrar y cada solicitud pendiente se vuelve a plantear, de modo que un reinicio nunca muestra una disposición a medias.

El ETag de la instantánea es "<epoch>-<rev>". rev aumenta con cada cambio visible para un lector, por lo que un 304 casi no cuesta nada al agente duradero. Una nueva época indica a Collie que el agente duradero se reinició. Collie sigue mostrando los paneles que tiene hasta leer la nueva instantánea. Luego lee cada panel con su cursor anterior y obtiene toda la vista actual del panel en una sola respuesta.

Una lectura fallida tras una correcta mantiene la última instantánea para ese sondeo. Dos fallos seguidos muestran el agente duradero como inaccesible. Una ruta de socket que no pasa la comprobación de privacidad queda inaccesible de inmediato.

Solicitudes y respuestas

Una solicitud es una tarjeta de pregunta, y permanece abierta desde el evento ask del agente duradero hasta su ask-closed.

estadoquién lo establecelo que muestra el teléfono
AbiertaEl agente duradero plantea la solicitud. El panel muestra waiting mientras haya alguna solicitud abiertaUna tarjeta en "Needs your answer", con el nombre del agente duradero y el tiempo restante cuando la solicitud tiene expiresAt
ModificadaEl agente duradero modifica la solicitud in situ, y su revision aumentaLa tarjeta se redibuja. Un toque en el formulario anterior devuelve 409 stale, y la tarjeta indica "This ask changed. Read it again, then tap an answer."
AceptadaEl teléfono responde y el agente duradero cierra la solicitud con by: "phone"La tarjeta desaparece y la herramienta se ejecuta o se deniega según indique la opción
Decidida en el agente duraderoEl agente duradero cierra la solicitud por sí mismo, decidedBy: "program". Una detención del turno cuentaUna línea en Chat que comienza con "Decided in the durable agent", con el título de la solicitud
Tiempo agotadoEl reloj supera expiresAt, decidedBy: "timeout"Una línea en Chat que comienza con "Timed out before an answer", con el título de la solicitud

Un toque posterior a la decisión recibe 409 decided con el primer resultado, y nada se ejecuta. La tarjeta indica entonces quién decidió primero: "Decided in the durable agent.", "Timed out before an answer." o, tras otro toque, "Already answered. This card goes away on the next update.". Una solicitud que el agente duradero ya no reconoce responde 200 too-late. La tarjeta muestra entonces "Not taken. The question may show again in a moment.", porque tras un reinicio el agente duradero puede volver a plantearla bajo el mismo id.

reglapor qué
El id de la solicitud es un hash del id del panel y del id de la llamada a la herramientaLa misma llamada a la herramienta planteada tras un reinicio tiene el mismo id, por lo que una respuesta enviada a través del reinicio llega a su destino
Una tarjeta permission se construye a partir del nombre de la herramienta y sus argumentos, nunca a partir de las palabras del modeloUn modelo que busque un sí describiría la llamada de forma favorable
Un agente duradero detrás de TLS no debe ofrecer allow-alwaysEl token es la única barrera, por lo que una sola respuesta de quien lo posea permitiría el paso a todas las llamadas posteriores
El teléfono no ofrece allow-always en una tarjeta cuyas palabras se hayan cortado o limpiado, o que no mencione ninguna herramientaLa persona no puede ver qué cubre la concesión
expiresAt es ISO 8601 con zona horariaPasada esta, la solicitud se decide mediante timeout, y las instantáneas dejan de listarla como abierta
El agente duradero conserva el resultado de al menos sus últimas 500 solicitudes decididas por panelUna pulsación tardía recibe decided y el primer resultado, no un simple too-late

Una solicitud es de uno de cuatro tipos: permission, choice, text o form. Cada una tiene su propio formato de respuesta, listado con Preguntas del SDK.

Identificadores de solicitud

Cada acción del teléfono tiene un id de petición, por lo que se ejecuta a lo sumo una vez.

El teléfono genera un id de petición por intención, y Collie escribe su propio recibo antes de pasar el id. El agente duradero conserva al menos los últimos 500 id de su época. La repetición de un id finalizado recibe la primera respuesta de nuevo con replayed: true y no ejecuta nada. El mismo id con otra carga útil recibe 409 request-id-reused.

Collie nunca reintenta un POST por sí mismo. Un POST que agota el tiempo de espera, pierde la conexión o recibe un 5xx tiene un resultado desconocido. Para una respuesta, la tarjeta muestra entonces "Not sure the answer arrived. Try again sends it once more.", y Reintentar envía el mismo id de petición, por lo que la memoria del agente duradero responde a la repetición.

Un reintento que encuentra la solicitud cerrada o el turno cambiado no puede determinar si el primer intento llegó. Collie responde entonces al teléfono "maybe applied", la tarjeta muestra "May already be applied. Check the chat.", y la acción nunca se envía una tercera vez.

Transportes

Un agente duradero utiliza uno de dos transportes: un socket privado en la máquina de Collie, o TLS con un token.

Los bytes son los mismos en ambos: las rutas, los cuerpos, la cabecera de versión, la ETag y los códigos de error. Solo difiere quién puede acceder al agente duradero.

a través del socketla regla
RutaAbsoluta, de a lo sumo 103 bytes. Ambos lados la leen desde COLLIE_DURABLE_SOCKET
ModosEl socket tiene modo 0600, en una carpeta con modo 0700. El agente duradero elimina los archivos de socket obsoletos antes de escuchar
El recorrido de la rutaAntes de cada conexión, Collie comprueba cada parte de la ruta con lstat. Ninguna parte es un enlace simbólico. La carpeta del socket le pertenece con modo 0700. Ninguna carpeta superior permite escritura a grupos u otros, excepto si es sticky como /tmp. El socket le pertenece, sin permisos para grupos u otros
Un recorrido fallidoCollie no se conecta, y muestra el agente duradero como inaccesible con socket-not-private y la parte que falló
TokenNinguna. El socket privado es el control de acceso
Quién puede actuarCualquier proceso de su usuario. El agente duradero puede rechazar a sus propios descendientes con 403 caller-refused
Tiempos de espera1000 ms para hello, snapshot y events. 3000 ms para una respuesta, envío, detención, acción, cambio de nombre o cierre. 30000 ms para un iniciador
Con qué frecuencia consulta CollieCada 1 s mientras un teléfono esté observando; de lo contrario, cada 3 s. A un agente duradero caído se le consulta una vez por sondeo
SistemasLinux y macOS. Windows no dispone de transporte por socket
mediante TLSla regla
URLhttps://, o http://127.0.0.1:<port> o http://localhost:<port> para una prueba local. Como máximo 2048 bytes, sin nombre de usuario ni contraseña, sin consulta, sin fragmento. Collie le añade /session/v1
TokenAl menos 32 bytes, ASCII imprimible sin espacios. Collie envía Authorization: Bearer <token> en cada petición, hello incluido
Comprobación del agente duraderoEl token primero, antes de la versión, hello y ready, comparado en tiempo constante. Un token ausente o incorrecto recibe un 401 { "code": "unauthorized" } simple y nada más
RedireccionesCollie no sigue ninguna. Una respuesta 3xx se propaga como estado, por lo que el token nunca llega a otro host
ETagUn proxy que comprime una respuesta puede debilitar la etiqueta a W/"<epoch>-<rev>". Ambas partes la comparan tras retirar W/
Un rechazoUn 401 o 403 muestra al agente duradero como inaccesible con token-refused
Tiempos de espera5000 ms para cada lectura y escritura, porque un agente duradero que estuvo suspendido puede reactivarse en frío. 30000 ms para un starter
Con qué frecuencia consulta CollieCada 2 s mientras un teléfono observa; si no, cada 10 s. A un agente duradero caído o rechazado se le consulta como máximo una vez cada 10 s

Cada tiempo de espera es un límite para todo el intercambio, desde la conexión hasta el último byte. Mediante TLS cada sondeo es una petición que el host puede facturar, un 304 incluido.

Límites

Collie corta o rechaza todo lo que supere estos límites, por lo que un agente duradero que se mantenga dentro de ellos no pierde nada.

quélímite
Espacios de trabajo por instantánea64
Pestañas por instantánea256
Paneles por instantánea256
Peticiones abiertas por panel50, las más antiguas primero
Opciones de un permission6
Opciones de un choice y de un campo de selección8
Campos de un form6
Starters por instantánea50
Botones de la barra por panel4, una etiqueta de 16 caracteres
Un idDe 1 a 128 bytes, sin caracteres de control, sin espacios en blanco, ninguno de /, ? o #
Un cuerpo de solicitud64 KiB, de lo contrario 413 too-large
Respuestashello 16 KiB, snapshot 4 MiB, events 8 MiB, conversations 1 MiB, items 8 MiB, un POST 16 KiB
Eventos por respuesta1000. Un lector rezagado recibe la vista actual, como máximo los 2000 elementos más recientes
Texto de un elemento user, reply, thinking o notice64 KiB
Texto de un elemento markdown o code32 KiB
Texto que envía el teléfono32 KiB
Un elemento linkSolo https://, 2048 caracteres como máximo
Una página de historial100 conversaciones o 1000 elementos
Un cursor de historial512 bytes de ASCII imprimible, sin espacios

Una cadena que supere su límite se recorta y se eliminan sus caracteres de control e invisibles. Una lista que supere su límite conserva sus primeras entradas. Una página de historial que supere su límite no se lee.

Versiones y el saludo descriptivo

Actualmente existe una versión de protocolo (wire), la 1, y Collie usa 1..1.

Cuando se lance la versión 2, Collie aceptará la versión 1 durante una versión menor posterior, y la versión menor siguiente dejará de admitirla. Un lector ignora campos, tipos de evento, clases de elemento o códigos desconocidos. Un campo añadido dentro de la versión 1, como expiresAt o decidedBy, es opcional. Un campo obligatorio nuevo, un significado nuevo para un campo existente o un campo eliminado requiere una versión nueva.

Una solicitud de un tipo desconocido para el teléfono se muestra como una que no puede responderse desde el teléfono, sin botones.

Cuando los dos rangos no coinciden, Collie no lee nada más del agente persistente. Envía un hello más por cada época del agente persistente, esta vez con su propia versión, para que el agente persistente pueda registrar la discrepancia en su lado. El agente persistente responde 409 incompatible con un refusal que indica ambos rangos. Este es el saludo informativo.

Collie escribe una línea en su registro por cada rango rechazado, y collie doctor muestra ambos rangos. La página principal del agente persistente en el teléfono muestra la misma frase, por ejemplo: "The durable agent speaks wire v2, this Collie speaks v1. Update Collie, or the agent's SDK." Actualice la parte más antigua.

Dónde se encuentran las reglas exactas

WIRE.md es el contrato, con cada estructura, código y regla.

Las decisiones subyacentes son registros en el repositorio:

registrolo que decide
ADR 0099Un agente durable es un multiplexor sin pantalla
ADR 0100Una consulta viaja como datos y se responde por id
ADR 0101Send y stop nombran el turno visto por el teléfono
ADR 0102Los iniciadores son filas en la página New
ADR 0103Los dos transportes
ADR 0104Un agente durable es una sesión y la salida
ADR 0105El SDK es un paquete npm

Editar esta página en GitHub

The rest of the documentation