09/Documentation
SDK для durable (экспериментально)
npm-пакет @colliepwa/durable-sdk по частям: точки входа и среды выполнения, openCollie, методы панели, четыре вида вопросов и requireApproval, хуки, история, caps, вспомогательные функции, интеграция с Pi и версии
Экспериментальная. Пакет, его API и сетевой протокол могут измениться, либо функциональность может быть удалена в следующем минорном релизе. Версии поясняет, что это означает для вашего durable agent.
@colliepwa/durable-sdk — это npm-пакет, с помощью которого durable agent отображает себя на вашем телефоне через Collie. На этой странице перечислены все его части. В Durable agents приведено краткое руководство и настройка на стороне Collie, а в Протокол durable wire объясняется, что передаётся между ними.
Установка и точки входа
Одна установка даёт пять точек входа: корневой импорт для большинства durable agents и четыре для более специфических задач.
npm install @colliepwa/durable-sdk@experimental
# or
bun add @colliepwa/durable-sdk@experimental| импорт | что содержит |
|---|---|
@colliepwa/durable-sdk | openCollie и весь API. На Bun сокет обслуживается сервером Bun, в остальных случаях — сервером node:http |
@colliepwa/durable-sdk/bun | Тот же API, всегда с сервером Bun |
@colliepwa/durable-sdk/node | Тот же API, всегда с сервером node:http, плюс NO_DESCENDANT_CHECK, строка, которую он выводит при запуске |
@colliepwa/durable-sdk/core | Интерфейс и сетевой протокол в виде одной функции, handle(request), для durable-агента со своим транспортом. Без импорта рантайма, поэтому работает везде, где работает веб-Request |
@colliepwa/durable-sdk/pi | Связующий код для durable-агента на базе Pi Durable (Вспомогательные функции Pi) |
Пакету требуется Node 22.19 или новее, либо Bun 1.4 или новее, и у него нет runtime-зависимостей. Для ./pi нужны @earendil-works/pi-durable, @earendil-works/pi-ai и @earendil-works/chord версий от 1.1 до 2. Точка входа протестирована с Pi Durable 1.1.0 и 1.2.0. Эти три пакета являются опциональными peer-зависимостями: durable-агент, который не импортирует ./pi, не устанавливает ни одной из них.
Рантайм определяет, может ли durable-агент распознать автора ответа. Проверка потомков отклоняет действие от самого durable-агента или запущенного им процесса с кодом 403 caller-refused. Она распространяется на answer, send, stop, action, rename, close, reopen и starter. Чтение остаётся доступным.
| рантайм | проверка потомков | что вы задали |
|---|---|---|
| Bun на Linux | Включено по умолчанию. Bun считывает идентификатор процесса вызывающей стороны из сокета | Ничего. callerCheck: "off" отключает её |
| Bun на macOS или любой другой системе, кроме Linux | Не может работать. Запуск завершается ошибкой с указанием callerCheck | callerCheck: "off" |
| Node, любая система | Не может работать: Node не может прочитать вызывающую сторону сокета. Durable-агент сообщает об этом в одной строке при запуске | Ничего. callerCheck не считывается |
Без этой проверки любой процесс вашего пользователя может ответить на карточку, включая запущенный агентом инструмент. Запускайте инструменты агента в песочнице, у которой нет доступа к сокету. Для сокета требуется система с владельцами файлов, поэтому на Windows openCollie завершает работу при старте. Вместо этого durable-агент там раздаёт ./core через TLS с токеном (Два способа связи с durable agent).
Открыть соединение
openCollie создаёт приватный сокет, а возвращённый дескриптор задаёт разметку для отображения на телефоне.
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();Если опция socket не задана, путь берётся из COLLIE_DURABLE_SOCKET — переменной, которую также читает Collie.
| опция | действие | по умолчанию |
|---|---|---|
socket | Путь к сокету: абсолютный, не более 103 байт. Его каталог создаётся с правами 0700 или уже должен принадлежать вам с правами 0700 | Переменная COLLIE_DURABLE_SOCKET. Если не задана ни одна, запуск завершается ошибкой |
hostName | Собственное имя durable-агента в его приветствии, усечённое до 64 байт. Обязательно | Нет |
tailLimit | Сколько необработанных событий хранит каждая панель для чтения Collie | 500, максимум 1000 |
caps | Заявленные возможности durable-агента (Возможности) | Всё, на что способен SDK |
callerCheck | descendant или off. Считывается только на Bun | descendant |
hooks | Одно именованное место для каждого действия, отправляемого телефоном (Хуки и история) | Нет |
warn | Куда SDK записывает свои однострочные примечания, например о Collie, использующем другую версию протокола | console.warn |
onRename | Устарело. Старое имя для hooks.onRename, оставленное на один релиз, без id запроса | Нет |
Ещё два параметра существуют только в createCore, но не в openCollie: receipts и allowAlways (Вопросы).
| на дескрипторе | что это такое |
|---|---|
address | Путь к сокету, который он слушает |
epoch | Новый и случайный при каждом запуске, 128 бит |
core | Ядро за сокетом. Тест или второй транспорт вызывает core.handle напрямую |
workspace(id, { title, cwd? }) | Рабочее пространство, создаваемое один раз на id. Его tab(id, { title }) даёт вкладку, а pane(id, options) вкладки — панель |
starters(list) | Что телефон может запустить со страницы New, не более 50. Каждое значение — { id, label, run }, и run разрешается в { paneId } показанной им панели |
history(provider) | Отдавать собственную запись бесед долговечного агента (Хуки и история) |
ready() | Вызывайте один раз, когда показаны все панели, и после перезапуска, когда все открытые ask снова подняты. До этого момента каждый маршрут, кроме hello, отвечает 503 starting |
close() | Остановить сервер. Ответы, которые уже отправляются, всё ещё уходят (максимум 2 с), затем файл сокета удаляется |
close() намеренно оставляет открытые ask открытыми: остановка не является ответом, и долговечный агент сам решает, что происходит с ожидающей их работой.
tab.pane(id, { title, harness, cwd?, sessionId? }) возвращает панель с этим id, если она существует, чтобы долговечный агент мог показать беседу дважды без создания второй панели. Заголовки усекаются до 256 байт, а harness — до 64. cwd должен быть абсолютным путём, иначе он опускается.
Каждый id следует правилу для id: от 1 до 128 байт, без управляющих символов, без пробелов и без /, ? или #. Недопустимый id возвращает TypeError. Id рабочего пространства или вкладки не может содержать :, так как в протоколе вкладка называется <workspace>:<tab>.
Панели
Панель — это одна беседа, и её методы определяют, что телефон отображает для неё.
| метод | что отображает телефон | лимит |
|---|---|---|
state(s) | working, waiting или idle. Изменение working начинает новый шаг | Пока открыт любой ask, состояние панели — waiting |
event(e) | Элементы чата: события item, remove, settled, reset и synced | См. таблицу элементов ниже |
subtitle(text) | Одна строка под заголовком. null очищает её | 120 символов |
badge(value) | { count } или { text } рядом с заголовком. null очищает его | Число от 0 до 9999, текст из 12 символов |
progress(value) | { kind: "steps", steps } или { kind: "percent", value, label? }, отображается, пока панель работает или ожидает. null очищает его | 12 шагов, каждая метка до 60 символов, значение от 0 до 100 |
actions(list) | Кнопки в секции belt долгоживущего агента: { id, label, icon?, busy?, disabled? }. null очищает их | 4 кнопки, метка до 16 символов |
onAction(fn) | Выполняет нажатие на одну из этих кнопок. Верните false, чтобы отклонить его | Телефон не отправляет нажатие для кнопки busy или disabled |
onSend(fn) | Принимает текст с телефона в виде fn(text, { steer, requestId }) | 32 КиБ текста |
onAbort(fn) | Принимает Stop в виде fn({ requestId }) | Нет |
ask(input, { signal? }) | Карточка вопроса (Вопросы) | 50 открытых запросов ask на панель |
updateAsk, decideAsk, outcomeOf | Изменить, решить или прочитать запрос ask (Вопросы) | Нет |
close() | Убирает панель из макета. Её открытые запросы ask закрываются со статусом stopped | Нет |
У панели также есть четыре поля только для чтения: id, sessionId, turnId (текущий шаг выполнения или последний) и openAsks. Поле icon действия принимает одно из значений: play, pause, check, x, refresh, archive, flag, star, send, note, search и more. При другом имени значок не отображается.
Событие item содержит один элемент с id и необязательным ts. Элемент с известным id заменяет предыдущий на месте.
| тип | что содержит | лимит |
|---|---|---|
user | Строка, отправленная пользователем. requestId указывает отправку, из которой она получена, поэтому телефон заменяет свою строку на неё | 64 КиБ текста |
reply, thinking, notice | Слова агента | 64 КиБ текста |
markdown | Текст, который телефон отображает как markdown: заголовки, списки, выделение, фрагменты кода и ссылки | 32 КиБ текста |
code | Блок кода с lang, например ts | 32 КиБ текста. lang содержит от 1 до 24 букв, цифр или _ + # . - |
link | href и необязательный label | href содержит только https://, не более 2048 символов. label не более 120 символов |
tool | Вызов инструмента: tool: { kind: "other", name, summary, output? } и status со значением running, done, failed или denied | name 128 байт, summary 1 КиБ, output 16 КиБ |
Элемент reply, thinking, notice или markdown может содержать partial: true, пока его текст увеличивается. Передавайте тот же id по мере роста текста не чаще чем каждые 250 мс, затем ещё один раз с итоговым текстом и без partial, до того как панель покинет working.
Текст сверх лимита обрезается, а управляющие и невидимые символы удаляются. Некорректный lang, некорректный href, некорректный badge или некорректный progress заменяются на TypeError или RangeError, так как Collie отбросил бы их. Долгоживущий агент не может сам добавлять события ask, ask-closed или state: их записывают ask() и state().
Вопросы
pane.ask показывает карточку и возвращает ответ, а requireApproval запрашивает подтверждение для одного вызова инструмента в одну строку.
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) формирует карточку на основе самого вызова, а не на основе слов модели о нём. Заголовок — «refund wants to run», строка инструмента — refund(order: "5521", amount: 40), в push-уведомлении указано «refund needs a yes», а кнопки — Allow и Deny. Возвращает { approved, decidedBy, decidedAt, askId }. Отклонение, тайм-аут, остановка и прерывание возвращают approved: false.
параметр requireApproval | действие | по умолчанию |
|---|---|---|
pane | Панель, которая запрашивает. Обязательно | Нет |
toolCallId | Собственный id вызова инструмента, сохраняющийся при перезапуске. Любая строка: значение, нарушающее правила для id, экранируется | Обязательно |
itemId | Элемент, под которым находится карточка | Id вызова инструмента |
timeoutMs | Сколько времени есть у телефона. По истечении вызов отклоняется с решением от timeout | Без ограничений |
signal | AbortSignal. Прерывание отклоняет вызов с решением от program | Нет |
labels | Текст на двух кнопках, { allow?, deny? } | Allow и Deny |
Используются две части, callSummary(name, args) и argumentsView(args): вызов в одну строку и аргументы в виде пар key: value, где каждое значение представлено в JSON.
pane.ask(input) принимает один из четырёх видов. Промис разрешается ответом в форме этого вида.
kind | что показывает карточка | ответ | лимит |
|---|---|---|---|
permission | По одной кнопке на вариант, каждая с effect: allow, allow-always, deny или cancel | { optionId, note? } | От 1 до 6 вариантов |
choice | По одной кнопке на вариант. При multiple: true пользователь выбирает несколько | { optionIds } | От 1 до 8 вариантов |
text | Одно текстовое поле с опциональным placeholder | { text } | maxLength от 1 до 2000, по умолчанию 500. Плейсхолдер — 60 символов |
form | От 1 до 6 полей, каждое вида text, choice или toggle, некоторые required | { values } с ключами по id полей | Поле выбора содержит от 1 до 8 вариантов |
Каждый вид принимает toolCallId, itemId и title (256 байт). Может принимать reason (2 КиБ), tool, push: { title?, line? } (60 и 120 символов, текст уведомления) и expiresAt (Date или строка ISO 8601 с часовым поясом).
Опустите id. SDK вычисляет его через askIdFor(paneId, toolCallId): SHA-256 от двух id, первые 32 шестнадцатеричных символа. Тот же вызов инструмента, повторённый после перезапуска, получает тот же id, и ответ, отправленный телефоном во время перезапуска, будет доставлен. Повторный вызов с уже открытым id возвращает TypeError.
| на панели | действие |
|---|---|
updateAsk(askId, patch) | Изменяет открытый запрос на месте: title, reason, tool, options, placeholder, maxLength или fields. Номер ревизии увеличивается на единицу, поэтому ответ на старую форму получает 409 stale, и телефон просит нажать снова. False, если запрос не открыт |
decideAsk(askId, answer?) | Durable-агент разрешил запрос сам, вне телефона. При answer ожидающий ask() разрешается этим значением. Без него он отклоняется с AskClosed. Позднее нажатие на телефоне получает 409 decided, а карточка сообщает: «Decided in the durable agent». False, если запрос не открыт |
outcomeOf(askId) | Первое решение: { decidedBy, decidedAt, optionId?, effect? }. Панель помнит свои последние 500. Undefined для запроса, который она не создавала или забыла |
decidedBy имеет значение phone, program или timeout. Запрос преодолевает свой expiresAt и закрывается с решением от timeout: ask() отклоняется с AskClosed, у которого decidedBy равен timeout. Карточка показывает оставшееся до этого момента время. Запрос, завершившийся по таймауту или разрешённый в durable-агенте, оставляет одну строку в Chat, например: «Timed out before an answer: refund wants to run».
Прерванный signal, pane.close() и закрытие с телефона закрывают запрос с решением от program, а ask() отклоняется с AskClosed.
Внимание. Вариантallow-alwaysпропускает все последующие вызовы после одного ответа. По https токен служит единственной защитой, поэтому durable agent там предлагает только Allow и Deny.createCoreсallowAlways: falseпревращает вариантallow-alwaysвTypeError. Телефон не предлагаетallow-alwaysдля запроса, слова которого были обрезаны или очищены, либо в котором не указан инструмент.
Каждое действие с телефона содержит request id, и ядро сохраняет квитанцию: повторный вызов ничего не запускает и возвращает первый ответ с replayed: true. Стандартный MemoryReceiptStore хранит самые свежие RECEIPTS_PER_GROUP (1000) для каждой панели, а также для каждой группы для стартеров, переименований, закрытий и повторных открытий. Повтор сброшенного id возвращает 500 receipt-dropped и ничего не запускает. Хранилище сбрасывается вместе с процессом.
Чтобы сохранять квитанции между перезапусками, напишите ReceiptStore с get(requestId) и put(requestId, record, group) и передайте его в createCore как receipts. openCollie всегда хранит их в памяти.
Хуки и история
Хук — это единая точка для действия, отправленного телефоном, а history provider отдаёт вашу собственную историю.
| хук | когда выполняется | как отклоняет |
|---|---|---|
onSend(pane, { text, steer, turnId, requestId }) | Текст для панели без pane.onSend | Исключение: 500 internal, неизвестный результат для телефона |
onAbort(pane, { turnId, requestId }) | Остановка для панели без pane.onAbort | Исключение, как указано выше |
onAction(pane, { actionId, turnId?, requestId }) | Нажатие пояса на панели без pane.onAction | Возврат false: 422 action-refused |
onRename({ kind, id, title }, requestId) | Новый заголовок для рабочей области или вкладки | Возврат false: 422 rename-refused |
onClose({ kind, id, paneIds }, requestId) | Телефон закрывает панель, вкладку или рабочую область | Возврат false: 422 close-refused |
onReopen({ id, paneId? }, requestId) | Телефон повторно открывает закрытую беседу | Возврат false: 422 reopen-refused |
Хук выполняется, только если включён соответствующий cap и его request id ещё не встречался. Отказ ничего не сохраняет, поэтому тот же request id может повторить попытку. Обработчики уровня панели имеют приоритет над хуком. Панель без того и другого отвечает 409 not-supported на отправку, остановку или нажатие.
SDK применяет принятое действие самостоятельно. Переименование задаёт заголовок. Закрытие удаляет цель со всем содержимым и закрывает их открытые запросы как остановленные. Повторное открытие без хука восстанавливает панель, закрытую этим процессом; для беседы, закрытой до перезапуска, требуется onReopen. Разметка создаётся заново при каждом запуске, поэтому durable agent, которому нужно сохранить заголовок или факт закрытия после завершения процесса, сохраняет это в своём хуке.
collie.history(provider) отдаёт все беседы, открытые и закрытые, из собственного хранилища durable agent. Включает cap history, если caps опущен или указывает на history: true.
HistoryProvider | возвращает |
|---|---|
list(after, limit) | { items, next? }: строки бесед, сначала новые, не более limit (100) |
items(id, after, limit) | { items, next? }: элементы беседы, сначала старые, каждый в последней версии, не более limit (1000). undefined для неизвестного id |
Строка представляет собой { id, title, subtitle?, workspaceId?, tabId?, startedAt, endedAt?, state, items }, где state имеет значение open или closed, а items указывает количество. Курсор (after, next) — это ваша собственная строка от 1 до 512 байт печатных символов ASCII без пробелов. Отсутствие next завершает список.
Когда провайдер задан, sessionId каждой панели совпадает с её pane id, и история отдаёт под ним беседу панели. Передайте sessionId в tab.pane(), чтобы указать другой id, или null, если он не может оставаться неизменным между перезапусками.
tailLimit — это не история. Это необработанный хвост событий, который каждая панель хранит для чтения событий в Collie, по умолчанию 500 событий. Читатель, отставший от него, получает вместо этого весь текущий снимок панели целиком, не более 2000 самых свежих элементов.
Возможности
Cap указывает, что durable agent умеет выполнять одно действие, а телефон отображает элемент управления только для cap, объявленного durable agent.
| ограничение | что принимает durable agent |
|---|---|
asks | Задаёт вопросы и принимает ответы |
starters | Выводит список стартеров и запускает один со страницы New |
send | Принимает текст с телефона |
steer | Принимает текст в текущий ход. Требуется send |
abort | Останавливает текущий ход |
rename | Принимает новый заголовок для рабочей области или вкладки |
close | Закрывает панель, вкладку или рабочую область |
actions | Выводит список кнопок панели инструментов и запускает одну из них |
history | Отдаёт свои диалоги, открытые и закрытые |
reopen | Снова показывает закрытый диалог |
Если параметр опущен, caps включает всё, что умеет SDK, а также history, как только у history() появится провайдер. Если указан, он задаёт весь список целиком: неназванное право отключается, поэтому { asks: true } объявляет только запросы. Чтобы отключить одно право и оставить остальные, разверните ALL_CAPS: { ...ALL_CAPS, steer: false }. Маршрут с отключённым правом возвращает 409 not-supported. Значение terminal всегда равно false.
Вспомогательные функции и константы
Корневой импорт также экспортирует части, из которых состоит openCollie, и применяемые им правила.
| export | что это такое |
|---|---|
createCore(options) | Ядро без сервера. Принимает параметры openCollie, кроме socket и callerCheck, а также receipts и allowAlways. Возвращает epoch, workspace, starters, history, ready, isReady и handle(request) |
handle | Сетевой протокол в виде одной функции: веб-Request на входе и Response на выходе. Обычная точка входа: core.handle(request) |
wireListener(core) | core.handle в виде слушателя запросов node:http, с drained() для корректного закрытия |
hello, versionLine | Ответ на приветствие и одна строка, которую долгоживущий агент записывает при отказе из-за версии |
mintId() | Новый случайный идентификатор: 128 бит в виде 32 шестнадцатеричных символов |
askIdFor(paneId, toolCallId) | Производный идентификатор запроса |
AskClosed | Ошибка, с которой отклоняется ask(), если ответ не пришёл. Содержит by и decidedBy |
idOk(id), assertId(id, what), safeId(raw) | Правило для идентификаторов: проверка, проверка с генерацией исключения и безопасный идентификатор из любой строки, одинаковый каждый раз |
cursorOk(cursor) | Правило для курсора истории |
cut(text, max, multiline?) | Очистите строку и обрежьте её до max байт с … на конце |
hrefOf, langOf, badgeOf, progressOf | Цель ссылки, язык кода, значок и прогресс, проверенные так же, как их проверяет панель |
subtitleOf, pushTextOf, renameTitleOf | Подзаголовок, ключевые слова отправки запроса и заголовок переименования, очищенные и обрезанные |
CAPS, LIMITS | Ограничения на каждое поле в байтах и ограничения на каждый список |
ACTION_LABEL_MAX, BADGE_TEXT_MAX, BADGE_COUNT_MAX | 16, 12 и 9999 |
SUBTITLE_MAX, LINK_LABEL_MAX, RENAME_TITLE_MAX | По 120 символов каждый |
PROGRESS_STEPS_MAX, PROGRESS_LABEL_MAX | 12 шагов, 60 символов |
PUSH_TITLE_MAX, PUSH_LINE_MAX, PLACEHOLDER_MAX | 60, 120 и 60 символов |
ANSWER_TEXT_MAX, ANSWER_TEXT_DEFAULT, ANSWER_TEXT_BYTES | 2000 и 500 символов, а также 8000 байт |
ALL_CAPS, PROTOCOL_RANGE, SOCKET_ENV | Все возможности протокола, версии сетевого протокола, поддерживаемые SDK, и имя COLLIE_DURABLE_SOCKET |
MemoryReceiptStore, RECEIPTS_PER_GROUP | Хранилище квитанций по умолчанию и его лимит в 1000 на группу |
Каждый тип сетевого протокола и полезная нагрузка каждого хука также экспортируются из src/core/types.ts.
Вспомогательные функции Pi
./pi превращает диалог Pi Durable в панель, вызов рискованного инструмента — в карточку, а хранилище Pi — в историю.
| export | действие |
|---|---|
showConversation(loc, harness, conversation, o) | Отображает диалог в виде панели: сначала историю, затем события в реальном времени. Send отправляется в submit у Pi с идентификатором запроса, а Stop — в его abort. Безопасно вызывать дважды |
PaneRegistry | Какая панель отображает какой диалог. После перезапуска reRaised(risky) ждёт, пока каждый рискованный вызов без результата не будет запрошен снова, поэтому ready() идёт после запросов |
riskGuard({ panes, risky, words?, timeoutMs?, onTimeout? }) | Расширение Pi, чей хук beforeTool превращает вызов инструмента из risky в карточку с вариантами Allow и Deny. Отклонённый вызов блокируется. При timeoutMs срок действия карточки истекает, оставшийся без ответа вызов блокируется, а onTimeout(tool, title) позволяет durable-агенту записать это в лог |
askTools({ panes, words, timeoutMs?, onTimeout? }) | Два инструмента службы поддержки для запросов: ask_queue (выбор варианта) и ask_customer (текстовый запрос). При timeoutMs запрос без ответа истекает по таймауту, и инструмент возвращает "timed out" |
spawnHelperTool(o) | Инструмент spawn_helper: дочерний диалог, отображаемый как новая панель, которая возвращает ответ помощника |
piHistory({ harness, panes, describe }) | HistoryProvider, который читает каждую запись каждого диалога Pi |
firstMessageOf(conversation) | Текст первого сообщения диалога для присвоения имени его панели |
paneIdOf(id), conversationOfPaneId(paneId) | Идентификатор панели диалога Pi, conv-<id>, и обратно |
summaryOf(args, name?) | Аргументы вызова инструмента словами, не более 200 символов |
Mapper | Записи Pi и события агента в виде элементов. Увеличивающийся ответ сохраняет один идентификатор элемента |
PARTIAL_MS, RE_RAISE_MS | 250 мс между двумя записями увеличивающегося ответа и максимум 5000 мс, которые ждёт reRaised |
ESCALATED | Пример словаря: уведомление службы поддержки для кнопки Escalate, которую showConversation добавляет с помощью escalate: true |
ASKING_TOOLS | Пример словаря: имена двух инструментов службы поддержки для запросов |
Submit, ReplyExtras | Типы пользовательского submit и элементов, которые durable-агент добавляет под готовым ответом |
Текст на карточке передаётся через параметры, поэтому ./pi не содержит текста из примера, кроме этих двух констант. Он написан для Pi Durable 1.1.0. Служба поддержки в examples/durable-member/ объединяет все части воедино.
Версии
Пакет имеет собственную версию, независимую от версии Collie, и указывает версию сетевого протокола, с которой он работает.
| сегодня | что оно означает | |
|---|---|---|
SDK_VERSION | 0.1.0 | Версия пакета. Пока пакет находится под dist-tag experimental, минорный релиз может изменить API |
WIRE_VERSION | 1 | Версия сетевого протокола durable, с которой работает пакет |
Collie работает с одной версией сетевого протокола и принимает предыдущую в течение одного минорного релиза после выхода новой. Если Collie не поддерживает ни одну из ваших версий, ядро выводит одну строку через warn, по разу на версию, например collie: Collie speaks wire v2, this durable agent speaks v1. Update the agent's SDK, or Collie. Телефон сообщает о несоответствии на главной странице durable-агента словами самого Collie. Обновите более старую сторону.
Пакет публикуется под npm dist-tag experimental, но никогда под latest. Если сетевой протокол durable будет удалён в выход, пакет объявляется устаревшим (ADR 0105).
Редактировать эту страницу на GitHub