本文へスキップ
ColliePWA

10/Documentation

durableの通信プロトコル(実験的機能)

Collieとdurable agent間で送受信される内容(開発者向け): ルート、helloとエポック、askのライフサイクルとリクエストID、ソケットおよびトークンによるトランスポート、制限事項、バージョン規則。詳細な仕様についてはWIRE.mdへのリンクを参照してください

実験的。 ワイヤの変更や、機能の削除が今後のマイナーリリースで行われる可能性があります。変更がどのように届くかについてはバージョンと情報通知用helloを参照してください。

durableワイヤは、Collieがdurable agentと通信するためのプロトコルです。このページでは、SDKを使わずにdurable agentを作成する開発者や、SDKの内部動作を把握したい開発者向けに解説します。厳密なルールはWIRE.mdに記載されており、このページと当該ファイルの内容が異なる場合はWIRE.mdが正となります。durable SDKがこれらすべてを自動で処理します。

送受信されるデータ

Collieが接続し、durable agentが待受を行います。各やり取りはJSONボディを伴う1つのHTTPリクエストです。

durable agentはプライベートなUnixソケット、またはURL(トランスポート)のTLS配下で待受を行います。Collieはこれをポーリングします。プッシュ通知、WebSocket、ストリームはありません。すべてのパスは/session/v1で始まります。これは固定の名前であり、バージョンではありません。最初のhelloを除くすべての呼び出しでは、ヘッダーX-Collie-Sessionでバージョンを渡します。リクエストボディは最大64 KiBの1つのJSONオブジェクトであり、空のPOSTボディは{}として読み取られます。

メソッドとパス機能応答上限
GET /hellodurable agentの名前、バージョン範囲、エポック、準備状態、機能16 KiB
GET /snapshotレイアウト情報。ワークスペース、タブ、各ペインの状態、ターン、保留中のask、starterが含まれます。ETagを付与し、変更がない場合は304を返します4 MiB
GET /pane/:id/events?after=N&epoch=E指定カーソル以降のペインのイベント8 MiB
POST /pane/:id/answeraskへの回答16 KiB
POST /pane/:id/sendペイン向けのテキスト。実行中のターンを誘導するか、次のターンを待機します16 KiB
POST /pane/:id/abort実行中のターンを停止16 KiB
POST /pane/:id/actionペインのベルトボタンのタップ16 KiB
POST /renameワークスペースまたはタブの新しいタイトル16 KiB
POST /closeペイン、タブ、またはワークスペースを閉じる16 KiB
POST /starter/:idstarterを実行。応答には新しいペイン名が含まれます16 KiB
GET /conversations?after=C&limit=Ndurable agentの会話一覧(オープンおよびクローズ)。新しい順1 MiB
GET /conversation/:id/items?after=C&limit=N1つの会話のアイテム一覧。古い順8 MiB
POST /reopenクローズされた会話を再表示16 KiB

すべてのエラーはcodeを含むJSONボディであり、409 staleや404 no-such-paneなどがあります。その他のパスは404 not-foundを返します。上限を超えた応答は読み取られず、応答が途切れたPOSTの結果は不明になります(リクエストID)。

Helloとエポック

helloはdurable agentの識別情報を表し、エポックはCollieが通信しているインスタンスの起動回次を表します。

helloのフィールド設定内容
service厳密にcollie-durable。これが一致しない場合、Collieはdurable agentを別のサーバーと見なし、それ以降の呼び出しを行いません
protocoldurable agentが対応するワイヤバージョンの範囲({ min, max })。現在は{ min: 1, max: 1 }
host.namedurable agent自身の名前。表示用テキストのみで最大64バイト
epochdurable agentの起動ごとにランダムに新規生成される値。128ビット以上で、再利用不可
ready起動後にdurable agentがペインを配置している間はfalse
capsdurable agentが実行可能な操作。各値は真偽値。存在しない機能はfalse

Collieはまずバージョンヘッダーを付けずにhelloを呼び出し、双方が対応する最も高いバージョンを選択して、以後のすべての呼び出しでそれを送信します。readyがfalseの間は、hello以外のすべてのルートが503 startingを返し、スマートフォン側ではdurable agentが起動中として表示されます。durable agentは、すべての会話が再表示され、すべての未解決のaskが再提起された後にのみreadyを設定するため、再起動によって中途半端なレイアウトが表示されることはありません。

スナップショットのETagは"<epoch>-<rev>"です。閲覧者に見える変更が発生するたびにrevが増加するため、304の処理コストはdurable agent側でほぼゼロです。新しいepochは、durable agentが再起動したことをCollieに伝えます。Collieは新しいスナップショットを読み取るまで、保持しているペインを表示し続けます。その後、各ペインを以前のカーソルで読み取り、1回の応答でペインの現在のビュー全体を取得します。

読み取りが成功した後に1回失敗した場合、そのポーリングでは最後のスナップショットが維持されます。2回連続で失敗すると、durable agentは到達不能として表示されます。プライバシーチェックに失敗したソケットパスは、直ちに到達不能となります。

AskとAnswer

askは質問カードであり、durable agentのaskイベントからask-closedまで未解決のまま開かれます。

状態設定者電話側に表示される内容
未解決durable agentがaskを提起します。いずれかのaskが開いている間、ペインはwaitingを読み取ります「要回答」の下にあるカード。durable agentの名前と、askにexpiresAtが設定されている場合はその残り時間が表示されます
変更済みdurable agentがその場でaskを変更し、revisionが増加しますカードが再描画されます。古いフォームをタップすると409 staleが返され、カードには「質問が変更されました。内容を再度確認してから回答をタップしてください。」と表示されます
回答済みスマートフォンが回答し、durable agentはby: "phone"でaskを閉じますカードは消去され、選択肢の指定に従ってツールが実行されるか拒否されます
durable agent側で決定済みdurable agent自身がaskを閉じます(decidedBy: "program")。ターンの停止もこれに該当しますChat内の「durable agent側で決定済み」で始まる行(askのタイトル付き)
タイムアウト時刻がexpiresAtを過ぎました(decidedBy: "timeout")Chat内の「回答前にタイムアウトしました」で始まる行(askのタイトル付き)

決定後に行われたタップは、最初の結果とともに409 decidedを受け取り、何も実行されません。その後、カードには最初に誰が決定したかが表示されます(「durable agent側で決定済み」、「回答前にタイムアウトしました」、または別のタップの後は「回答済みです。このカードは次回の更新で消去されます。」)。durable agentが認識しなくなったaskは200 too-lateを返します。再起動後にdurable agentが同じIDで再度提起する可能性があるため、カードには「処理されませんでした。質問はすぐに再表示される場合があります。」と表示されます。

ルール理由
askのIDはペインIDとツール呼び出しIDのハッシュです再起動後に提起された同一のツール呼び出しは同じIDを持つため、再起動をまたいで送信された回答も正常に届きます
permissionカードはツールの名前と引数から生成され、モデルの文言から生成されることは決してありません「はい」を望むモデルは、呼び出しを好意的に説明する傾向があります
TLS配下のdurable agentはallow-alwaysを提供すべきではありませんトークンのみが認証手段であるため、トークン保持者からの回答が1つあれば、以後のすべての呼び出しが通過してしまいます
文言が切り詰められたか整理されたカード、またはツール名のないカードでは、スマートフォン側にallow-alwaysが表示されませんユーザーには、付与された権限の適用範囲が見えません
expiresAtはタイムゾーン付きのISO 8601形式ですそれを過ぎるとaskはtimeoutによって判定され、スナップショットの一覧でもオープン状態として表示されなくなります
durable agentは、ペインごとに判定済みの直近500件以上のaskの結果を保持します遅れてタップされた場合は、単なるtoo-lateではなくdecidedと最初の結果が返されます

askにはpermission、choice、text、formの4種類があります。それぞれ応答の形式が異なり、SDKの質問に記載されています。

リクエストID

スマートフォンからの各操作にはリクエストIDが付与されるため、実行は最大1回に限られます。

スマートフォンはインテントごとに1つのリクエストIDを生成し、CollieはそのIDを渡す前に自身のレシートを書き込みます。durable agentは自エポックの直近500件以上のIDを保持します。完了済みIDの再送にはreplayed: trueを付けて最初の応答が再送され、何も実行されません。同じIDでペイロードが異なる場合は409 request-id-reusedが返されます。

Collieが独自にPOSTを再試行することはありません。タイムアウト、接続切断、または5xxが返されたPOSTの結果は不明となります。その場合、回答用のカードには「Not sure the answer arrived. Try again sends it once more.」と表示されます。「Try again」を押すと同一のリクエストIDが送信され、durable agentのメモリが再試行に応答します。

再試行時にaskがすでに閉じられているかターンが遷移していた場合、最初の試行が成功したかどうかを判断できません。その場合、Collieはスマートフォンに「maybe applied」と応答し、カードには「May already be applied. Check the chat.」と表示され、操作が3回送信されることはありません。

トランスポート

durable agentは、Collieが稼働するマシン上のプライベートソケット、またはトークン認証を伴うTLSのいずれかのトランスポートを使用します。

ルート、ボディ、バージョンヘッダー、ETag、エラーコードなど、送受信されるバイトデータはどちらも同一です。異なるのは、どの主体がdurable agentにアクセスできるかという点のみです。

ソケット経由規則
パス絶対パスで、最大103バイトです。双方がCOLLIE_DURABLE_SOCKETから読み取ります
モードソケットのモードは0600で、モード0700のフォルダー内に配置されます。durable agentはリッスンを開始する前に、古いソケットファイルを削除します
パスの巡回接続するたびに、Collieはパスの各構成要素をlstatで検証します。シンボリックリンクは許可されません。ソケットが配置されたフォルダーの所有者は実行ユーザーであり、モードは0700である必要があります。/tmpなどのスティッキービット付きフォルダーを除き、それより上位のフォルダーにグループまたはその他の書き込み権限があってはなりません。ソケットは実行ユーザーが所有し、グループやその他のパーミッションを持ちません
巡回の失敗Collieは接続を行わず、socket-not-privateおよび問題のあった箇所を示して、durable agentに到達できない旨を表示します
トークンなし。プライベートソケット自体がゲートとして機能します
実行可能な主体実行ユーザーに属する任意のプロセスです。durable agentは自らの子孫プロセスを403 caller-refusedで拒否できます
タイムアウトhello、snapshot、eventsは1000ミリ秒。answer、send、stop、action、rename、closeは3000ミリ秒。starterは30000ミリ秒です
Collie のポーリング間隔スマートフォンの監視中は1秒ごと、それ以外は3秒ごとです。停止中のdurable agentにはポーリングごとに1回問い合わせが行われます
システムLinuxおよびmacOS。Windowsにはソケットトランスポートがありません
TLS経由規則
URLhttps://、またはローカルテスト用のhttp://127.0.0.1:<port>やhttp://localhost:<port>。最大2048バイト、ユーザー名・パスワード・クエリ・フラグメントは不可。Collieがこれに/session/v1を追加します
トークン32バイト以上のスペースを含まない印刷可能ASCII。Collieはhelloを含むすべてのリクエストでAuthorization: Bearer <token>を送信します
durable agentによる検証トークンを最優先で検証し、バージョン、hello、readyよりも先に定数時間で比較します。トークンが存在しないか誤っている場合は、何も含めず単に401 { "code": "unauthorized" }を返します
リダイレクトCollieはリダイレクトを追跡しません。3xxはステータスとしてそのまま上位に渡されるため、トークンが別のホストに送信されることはありません
ETagレスポンスを圧縮するプロキシは、タグをW/"<epoch>-<rev>"に弱める場合があります。双方はW/を取り除いて比較します
拒否401または403の場合、durable agentはtoken-refusedで到達不能として表示されます
タイムアウト読み取りと書き込みにはそれぞれ5000ミリ秒を指定します。スリープしていたdurable agentがコールドスタートする可能性があるためです。スターターには30000ミリ秒を指定します
Collie のポーリング間隔スマートフォンが表示中の場合は2秒ごと、それ以外は10秒ごと。停止中または拒否されたdurable agentへの問い合わせは、最大でも10秒に1回です

各タイムアウトは、接続から最後のバイトまでの通信全体に対する期限です。TLS経由の場合、ポーリングはすべてホストの課金対象となる可能性があり、これには304も含まれます。

制限事項

Collieはこれらの制限を超えたものを切断または拒否するため、制限内に収まっているdurable agentでデータが失われることはありません。

項目制限
スナップショットあたりのワークスペース数64
スナップショットあたりのタブ数256
スナップショットあたりのペイン数256
ペインあたりの未解決の問い合わせ数50件、古い順
permissionのオプション数6
choiceおよび選択フィールドのオプション数8
formのフィールド数6
スナップショットあたりのスターター数50
ペインあたりのベルトボタン数4個、ラベルは16文字
id1〜128バイト。制御文字、空白文字、/、?、#は使用不可
リクエストボディ64 KiB。超過時は413 too-large
レスポンスhello 16 KiB、snapshot 4 MiB、events 8 MiB、conversations 1 MiB、items 8 MiB、POST 16 KiB
レスポンスあたりのイベント数1000件。処理が遅延したリーダーには現在のビュー(最新の最大2000件)を返却
user、reply、thinking、noticeアイテムのテキスト64 KiB
markdownまたはcodeアイテムのテキスト32 KiB
スマートフォンが送信するテキスト32 KiB
linkアイテムhttps://のみ、最大2048文字
履歴ページ100件の会話、または1000件のアイテム
履歴カーソル512バイトの印字可能ASCII文字、スペース不可

制限長を超えた文字列は切り詰められ、制御文字や不可視文字は削除されます。制限数を超えたリストは先頭のエントリが保持されます。制限サイズを超えた履歴ページは一切読み込まれません。

バージョンと情報通知用hello

現在の通信プロトコルバージョンは1のみであり、Collieは1..1を使用します。

バージョン2のリリース後、Collieは1マイナーリリースの間バージョン1を受け付け、その次のマイナーリリースでサポートを終了します。リーダーは未知のフィールド、イベント種別、アイテム種別、コードを無視します。expiresAtやdecidedByなど、バージョン1内で追加されたフィールドは任意です。新しい必須フィールド、既存フィールドの意味変更、フィールドの削除には新しいバージョンが必要です。

スマートフォンが認識できない種類の問い合わせは、端末から回答できないものとしてボタンなしで表示されます。

2つの範囲が重複しない場合、Collieはdurable agentからの読み込みを停止します。durable agentのエポックごとに1回だけ、Collieは自身のバージョンを含めてhelloを再度送信し、durable agent側で不整合をログに記録できるようにします。durable agentは両方の範囲を指定したrefusalとともに409 incompatibleを返します。これが通知用hello(telling hello)です。

Collieは拒絶した範囲ごとにログへ1行出力し、collie doctorに両方の範囲を表示します。スマートフォンのdurable agent画面にも同様のメッセージ(例:「The durable agent speaks wire v2, this Collie speaks v1. Update Collie, or the agent's SDK.」)が表示されます。古い側を更新してください。

詳細な仕様の記載場所

WIRE.mdがコントラクトであり、すべての形状、コード、ルールを定義しています。

その背景にある設計判断は、リポジトリ内のレコードに記載されています。

レコード決定内容
ADR 0099durable agentは画面を持たないマルチプレクサー
ADR 0100askはデータとして送られ、idによって回答される
ADR 0101sendとstopは端末に表示されたターンを指定する
ADR 0102starterは新規作成ページの各行
ADR 01032つのトランスポート
ADR 0104durable agentはセッションであり、その出口
ADR 0105SDKはnpmパッケージ

GitHub でこのページを編集

The rest of the documentation