Bot Mode
目次
Bot Mode は Hermes のプロファイル を、名前を持つ Bot の一覧に変えるものです。それぞれの Bot は自分の役割、モデル、記憶、スキル、アバターを持ちます。Bot は繰り返しの作業をこなし、グループチャットで一緒に検討し、互いに直接メッセージを送り合います。専門役の Bot を一度作れば、あとはずっとそこにいて、クリック 1 つで呼び出せます。
Bot Mode は デスクトップアプリ に組み込まれて 提供され、既定で有効 です。インストールは要りません。左のサイドバーで Sessions の隣に Bots タブとして現れ、Bots タブを開いている間は会話の横に Routines のタイルが並びます。
プロファイルから移ってきた場合
プロファイルはこれまでとまったく同じように使えます。Bot Mode は、プロファイルだけでは持てない部分を足します。
| プロファイルだけの場合 | Bot Mode の場合 |
|---|---|
| プロファイルごとにセッションが積み重なり、その中から1つを選ぶか新しく始めます | Bot ごとに、ずっと続く Bot Chat が1つだけあります。Bot をクリックすれば同じ会話に戻れます。/new は会話を枝分かれさせず、圧縮します |
| 別の専門家と話すにはプロファイルを切り替えます | すべての Bot が1つの一覧に、アバター、最新のメッセージ、未読の状態とともに並びます |
| プロファイル同士はやり取りしません | Bot は互いにメッセージを送り合い、グループチャットを共有します |
定期ジョブは hermes cron にあり、チャットとは切り離されています |
各 Bot の定期タスクは、そのチャットの隣で予定を組み、編集します |
何も移動しません。設定、記憶、スキル、認証情報は ~/.hermes/profiles/<name>/ に置かれたままで、hermes -p <bot> chat でも同じエージェントが開きます。
Bots ペイン
一覧にはエージェントのプロファイルごとに 1 行が並び、アバター、直近のメッセージの抜粋、時刻が表示されます。
- Bot をクリック するとそのチャットに入ります。どの Bot にも、生まれた瞬間に作られて(そして固定される)唯一の恒久的な Bot Chat の会話があります。行をクリックすると常にその Bot Chat が開きます(行に抜粋されているのと同じ会話です)。その Bot について別のタブを開いていても同じで、それらのタブは横に開いたまま残ります。タブの並びでは Bot Chat に Bot の名前が付くので、2 つの Bot を開いていてもひと目で見分けられます。
- Bot を右クリック → Open recent session で、その Bot が直近に動かしていた普通の会話(定期タスクの実行、任せた仕事、脇道の相談など)へ、Bot Chat の隣のタブとして飛べます。行のクリックの挙動は変わりません。ほかに会話がまだない Bot なら、そのまま Bot Chat が開きます。
- Active now — 一覧の稼働の絞り込みには、いま画面で動いている番の持ち主、直近 90 秒以内に発言した Bot、そして少し前にワーカーの生存信号があった Bot が入ります。ゲートウェイにつながっているというだけでは、その Bot が働いていることにはなりません。
- Search は入力に応じて一覧を絞り込みます。
- Bot を隠す — 行を右クリック → Hide Bot で、使っていない Bot を一覧と Active now の帯から外せます。隠すのは表示上だけの操作です。@メンションはこれまでどおり解決され、グループチャットの所属もそのまま、定期タスクも動き続けます。1 つでも隠すと、ペインのヘッダーに 目のアイコン が現れます。これをクリックすると隠れている Bot が薄く表示され、右クリック → Unhide Bot で戻せます。隠れている Bot は通知を出しませんが、未読の動きは静かに溜まり、目のアイコンに点が付いて何かあったことを知らせます。隠しているかどうかは Bot のプロファイルのメタデータに保存されるので、そのバックエンドに接続しているすべてのデスクトップに引き継がれます。
Bot をセクションに整理する
セクションは自分で作るフォルダーです。Clients、Team など、しっくりくる名前で構いません。ゲートウェイごとの自動的なまとまりとは別の、もう 1 つの軸になります。セクションを作っていなければ、一覧は従来どおりの素の並びのままです。
- 作成 は、ペインの + メニュー → New section、または Bot を右クリック → Move to section → New section…(この場合は作成と同時にその Bot が入ります)。
- Bot を入れる には、行をセクションへドラッグします。重ねている間は入れ先が強調され、Esc でドラッグを取り消せます。右クリック → Move to section から選ぶこともできます。Remove from section で Unassigned に戻ります。
- 名前の変更、並べ替え、削除 は見出しの右クリックメニュー(またはカーソルを重ねると出る ⋯)から行います。見出しをダブルクリックしても名前を変えられます。見出しはゲートウェイの見出しと同じようにたためます。
- セクションを削除しても Bot は消えません。Bot は Unassigned に戻り、通知から Undo で取り消せます。確認は求められません。
所属は、セクションの id と名前が各 Bot のプロファイルのメタデータ(ui_meta)に保存されるので、Bot のセクションはそのバックエンドに接続しているすべてのデスクトップに引き継がれます。2 台目のデスクトップは、一覧を最初に読み込んだときにセクションの見出しを所属する Bot から組み立て直しますし、片方で名前を変えたときも同じ仕組みで他方に伝わります。セクションの一覧そのもの(並び順や空のセクション)はデスクトップごとに保たれるので、1 台でセクションを消しても、ほかの端末ではそこで消すまで空の見出しが残ります。名前が一緒に運ばれるようになる前に振り分けた Bot は id しか持っていませんが、そのセクションを作ったデスクトップが次に一覧を読み込んだときに名前を自動で書き込み、ほかのデスクトップはそこから受け取ります。一覧に複数のゲートウェイが並んでいる場合、セクションは各ゲートウェイのまとまりの中に入れ子になります。
Bot を作る
一覧で New Agent を押します。手早く作る場合は Name、Title、Description の 3 つを埋めるだけで、Bot は数秒で出来上がり、新しい Bot Chat の最初のメッセージとして自己紹介します。
Advanced を開くと、設定できる項目がすべて現れます。
- 既存のプロファイルから複製 — 別の Bot の設定、スキル、SOUL、記憶を引き継いで始めます。まっさらから始めるなら Fresh profile を選びます。
- Create empty — 同梱のスキルをすべて省いて、最小限のプロファイルにします。
- モデルとプロバイダーの固定 — その Bot に専用のモデルを割り当てます。Hermes が知っているプロバイダーとモデルの組み合わせなら何でも使え、別々のモデルで動く Bot を並べて運用できます。設定しなければ、起動したプロファイルの設定を引き継ぎます。Bot Chat の入力欄からモデルを選ぶと、その選択はそのチャットに残ります(アプリを開き直しても残ります)。Bot のプロファイル側のモデルを変更すると、そちらが改めて優先されます。
- 独自の SOUL.md — その Bot の人格と、常に効く指示です。
- スキル単位、ツールセット単位、MCP サーバー単位の有効化 — その専門役に必要な機能だけに印を付けます。
- 主プロファイルから API キーを複製 — 既定で有効です。Bot はそれぞれ自分の認証情報の保管先を持ちます。固定の API キーはそこへ複製されますが、1 回きりの OAuth ログイン(Anthropic、OpenAI Codex、xAI)は複製されません。その Bot 自身で
hermes -p <name> auth add <provider>を実行してログインしてください。詳しくは プロファイルはそれぞれ自分の認証情報を持ちます をご覧ください。
どの端末に置くかを選ぶ("Create on")
Settings → Connections に複数の接続を登録していると、New Agent のダイアログに Create on の選択欄が加わります。端末を選ぶと、プロファイルは その 端末のバックエンドに作られ、いま見ているウィンドウのゲートウェイは切り替わりません。新しい Bot は接続先の Bot として一覧に現れ(同じ名前が複数の端末に存在する場合は @name-device の形の呼び名が付きます)、そこへ話しかけると、その端末側へ処理が回ります。このとき Clone from profile に並ぶのは、いま見ているウィンドウの一覧ではなく、対象の端末に実際にあるもの(その端末の default、または Fresh profile)です。離れた端末にまっさらな Bot を作るために、ゲートウェイを切り替える必要はありません。
接続が 1 つだけの場合(ほとんどはこちらです)、この選択欄は表示されず、Bot はいま接続している端末に作られます。従来どおりの動きです。
離れた端末に作るときの注意点です。
- 複製元 は *対象の* 端末のプロファイル(その
default)になります。離れた端末には、手元のプロファイルがないからです。 - Capabilities タブは対象の端末のバックエンドに固定されるので、作成中に設定したスキル、ツール、MCP サーバーは、その Bot が住む端末に反映されます。(古いデスクトップでは、離れた端末を選んだときに事前登録型のスキル・ツール・MCP のチェックリストに切り替わります。どちらも対象の端末の一覧を読み取ります。)
- ダイアログを取り消すと、作りかけのプロファイルは、作られた端末の側で破棄されます。
Edit Profile(Bot を右クリック)を使えば、稼働中のプロファイルに対して同じ画面をいつでも開き直せます。アバター、タイトル、説明、モデルの固定、スキル、ツールセット、MCP サーバー、そして SOUL.md の全体を編集できます。
Duplicate(右クリック)は、Bot を丸ごと複製します。設定、スキル、SOUL.md、記憶、見た目まで含みます。Delete Profile は Bot を完全に削除します。デスクトップのプロファイルメニューと同じ、取り返しのつかない操作向けの確認を挟みます。既定のプロファイルは削除できません。
アバター
どの Bot にも顔が付きます。
- ブロブの顔(既定) — Bot の名前から決まる、やわらかい形の顔です。名前が同じなら、いつでも同じ顔になります。New Agent で名前を入力している間、顔はその場で追随します。Randomize で引き直し、Lock face で気に入った顔を名前が変わっても固定でき、6 種類のシルエット(round、organic、boxy、nub、cloud、sun)のどれかを指定しつつ、ほかの要素は名前から決めさせることもできます。
- 幾何学的な顔 — 従来からある 7 形状 × 10 色です。画面で動いている番の間、その持ち主の Bot は身を傾けて上を見上げ、3 つの点が動きます。番が終わると、ゆっくり待機の姿に戻ります。持ち主の判定には接続も含まれるので、別のゲートウェイにいる同名の Bot がその姿を借りることはありません。裏で動くワーカーはこれまでどおりの作業中の動きのままで、写真、ブロブの顔、紋章もそれぞれの見た目のままです。
- 画像のアップロード — 好きな絵を使えます。
- AI が生成した肖像 — 画像のバックエンドを設定していれば、その場で生成できます(標準の
image.generateRPC を使うので、手元のゲートウェイでも離れたゲートウェイでも動きます)。 - ドット絵のペット — petdex のギャラリー から選んだ相棒が、Bot の作業中にアバターの横で跳ねます。端末で
hermes petsを実行するとギャラリーを見られます。
Bot の見た目、タイトル、説明はバックエンド側のプロファイルのメタデータに保存されるので、そのバックエンドに接続しているどのデスクトップでも同じ姿で現れます。
声
Bot がしゃべるときに使うのは、その Bot 自身のプロファイル の読み上げ設定(そのプロファイルの config.yaml にある tts.*)で、しゃべらせる先も その Bot 自身のゲートウェイ です。Bot のチャットでの読み上げ、自動読み上げ、音声での会話は、分割した小窓で開いていても主画面で開いていても、すべてその Bot の(接続、プロファイル)の組み合わせで音声にされます。だから、設定の違う 2 体の Bot は違う声で話し、別々のゲートウェイに同じプロファイル名の Bot がいても声を共有することはありません。tts.* を自分で持っていない Bot のプロファイルは、そのプロファイル側のサーバーの既定値を使います。持ち主のいないチャット(ふつうのセッション)だけが、いま使っているプロファイルの声を使います。Bot のチャットでの音声入力は、これまでどおり、いま使っているプロファイルの音声認識の設定を使います。
Routines
Routines ペインは、繰り返しの作業を、それを担当する Bot に結び付けます。「毎朝、受信箱をまとめて」は、その担当の Bot のすぐ隣に置かれます。このペインは Bots タブを開いている間だけチャットの横に並び、Sessions に戻ると引っ込みます(古いデスクトップでは常に表示されたままです)。✕ で閉じると、Bots タブをいったん離れて戻ってくるまで隠れたままになり、戻ってくると右端のたたまれたタブとして復活します。スケジュールは構造化された選択画面で組み立てます(まず頻度を選び、そのあと必要な細部だけを指定します)。Advanced の欄では Hermes のスケジュール文字列を直接書けます。
Routines は [bot:<name>] <routine> という名前空間を持つ、ただの Hermes の cron ジョブ です。hermes cron list にも、本体の Cron ページにも現れます。実行結果はその Bot 自身のチャット履歴に入るので、ちょうどその Bot に話しかける場所に結果が届きます。
グループとグループチャット
参加者の番が動いている間に送ったメッセージは、同じスレッドへの返信も含めて、 進行中の部屋の処理のうしろに並びます。その参加者に割り込むことはなく、まだ見ていない メッセージが既読になることもありません。Stop を押すと、並んでいた続きの処理が取り消され、 再開するまで参加者は止まったままになります。止まっている参加者を動かすには、その参加者を @ で名指しするか、 部屋全体に呼びかけます(@all … / @everyone …。言い回しは自由です)。呼びかければ全員が動き出すので、 @all resume という決まった唱え文句が要るわけではありません。stop・halt・pause で参加者が止まるのは、 その語が @ の名指しのすぐ隣にあるときだけです(stop @bot、@bot please pause)。文中のほかの場所に 同じ語があっても、ふつうの文章として読まれます。ドイツ語の halt が、送った相手の bot を黙らせてしまうことは もうありません。ただし、そうしたメッセージで止まっている参加者が動き出すこともありません (@bot please just stop now で目を覚ますことはなく、止めたいなら名指しの隣でもう一度止める語を書きます)。 コードブロック、インラインコード、引用、引用行(blockquote)の中にある止める語は内容として扱われ、指示にはならないので、 誰も止まりません。止まっていた参加者は、止まっている間に飛ばしたメッセージを、止まるきっかけになった メッセージも含めて、再開後の最初の番で受け取ります。そのため、宛てられたメッセージが失われることはありません。 「stop」をコマンドとして使わない部屋では、グループ設定のダイアログで Detect stop directives をオフにできます。 どちらの場合でも、Stop ボタンは実行中の処理を取り消します。 作業を続けているのが見てとれる参加者は、最大 3 時間まで自分の番を持ち続けます (作業の報告が途切れた参加者は、それに関わらず 3 分の沈黙で番を失います)。静かになった部屋は、画面側の 待ち時間が終わったあとも、時間切れになった参加者をさらに 3 時間見守ります。この見守りの時間が、 番そのものを延ばすことはありません。 解決していない参加者の失敗は、部屋が落ち着いたあとも、たたまれた Activity の要約に表示されたまま残ります。 参加者のバックエンド自体が番に失敗した場合(認証情報の誤り、プロバイダー側のエラーなど)も同じで、 ゲートウェイから報告が届いた時点でそのまま伝わります。20 分間考え込んでいるように見えることはありません。 失敗の行には原因が書かれます。builder hit an error — <first line of the error>(秘密情報らしい文字列は伏せられ、長い行は切り詰められます)です。 Activity を開くと番の流れを確認できます。やり直すには、その参加者にもう一度話しかけてください。 送信が成功したか失敗したか分からない場合、自動で送り直すことはありません。
手元の Bot を右クリック → Manage groups で、いくつでもグループチャットに追加したり外したりできます。既存のグループを個別に選ぶことも、その場で新しく作ることもできます。手元の所属はバックエンドと同期されるプロファイルのメタデータに保存されるので、複数のデスクトップ間で引き継がれます。従来の 1 グループだけを持つ古いプロファイルも、そのまま動きます。接続先の Bot は New Group Chat の選択画面から参加し、その部屋の共有状態の中でも、どこの所属かが分かる形で保たれます。
すでにある部屋の顔ぶれをまとめて入れ替えるには Manage members を使います。部屋のヘッダーの人型のアイコンか、Group settings の Manage members… のボタンから開きます。一覧には今の参加者があらかじめ選ばれた状態で、手元の Bot と接続先の Bot がすべて並びます。何人かをまとめて追加・削除して Save members を押すと、新しい顔ぶれ(人数は 2〜6 の Bot のまま)が適用され、部屋も履歴も各参加者の部屋のセッションもそのまま残ります。外された Bot はそれ以降の番を受け持たず、加わった Bot は最初の番で直近の部屋の履歴を読みます。Cancel を押せば何も変わりません。
各参加者の番には、その参加者自身の前回の番より後に部屋へ届いたメッセージがすべて渡ります。上限はおよそ 200 件、またはやり取り 32,000 文字のうち、先に埋まったほうまでです。極端に長いメッセージが 1 件ある場合は、周りのメッセージを押しのけてしまわないように、印を付けた 8,000 文字の抜粋に切り詰めます(部屋の記録にも同じ抜粋が残ります)。それでも収まりきらないときは、前のメッセージを何件省いたかがプロンプトに明記されます。
部屋はデスクトップ 1 台ではなく、ゲートウェイに付いてきます。 各部屋の直近のやり取り、参加者、画像、名前は、デスクトップが接続している すべての ゲートウェイの共有プロファイルメタデータへ写されます。ゲートウェイごとにバージョンを持つので、2 台のデスクトップが同時に書き込んでも、上書きではなく統合されます。同じゲートウェイに対して別の端末で Hermes Desktop を開けば(ローカルネットワーク、Tailscale、どこからでも)、その部屋が履歴付きで現れます。ゲートウェイだけのクライアントからも見えます。部屋は内部に変わらない識別子を持つので、名前を変えても各所で表示名が変わるだけ、解散すればどのクライアントからも恒久的に消え(そのとき接続していなかったクライアントからも消えます)。解散したことはデスクトップ自身が覚えているので、削除を受け取り損ねた写しを持つゲートウェイがその部屋を復活させることはできません。同じ名前で作り直せば本当に新しい部屋として始まります。ゲートウェイが落ちたり取り外されたりしても、失われるものはありません。接続していた各デスクトップが部屋の全体を手元に保持していて、つなぎ直したゲートウェイへ内容を戻します。(やり取りの完全な記録は各デスクトップの手元の保存領域に残ります。共有されるのは、直近の履歴に限った写しです。)
グループの顔ぶれを示す名前と画像は、作るときにも、作ったあとにも変えられます。
- New Group Chat では、名前と一緒に 部屋の画像 を任意で設定できます。端末からアップロードするか、(画像のバックエンドを設定していれば)生成します。仕組みは Bot のアバターと同じです。画像は一覧の行に(既定のグループの記号の代わりに)表示され、部屋のヘッダーではタイトルの前に並びます。
- 部屋のヘッダーにある 歯車 のボタンで Group settings が開き、グループの 名前の変更 や、画像の設定・差し替え・削除をいつでも行えます。名前を変えると、部屋の記録、各参加者の部屋のセッション、所属、画像がすべて一緒に引き継がれるので、履歴は失われません。すでに使われている名前への変更は、黙って番号を付け足すのではなく、はっきり拒否されます。
- Group settings には、参加者ごとに Compress history のボタンも並びます。各参加者は部屋ごとに見えないセッションを持っていて、番を重ねるたびに膨らみます。これが大きくなりすぎると、その参加者は空の返答(
The model returned no response after processing tool results)を返すようになります。Compress history は、その見えないセッションに対して/compressと同じ圧縮をかけ(サイドバーからも部屋の入力欄からも届かない操作です)、何件のメッセージをまとめたかを知らせます。圧縮は一度に 1 人ずつ行ってください。部屋の記録そのものには手を付けません。
グループは、Bot との個別チャットと同じ「動きのあった順」の一覧に、独立した行として並びます。1 つの Bot は複数のグループに属していても個別チャットの行を 1 つだけ持ち、グループはそれぞれ自分の行を持って、参加人数、直近のメッセージの抜粋、時刻、あなたの判断待ちかどうかを表示します。
部屋の行も、Bot の行と同じように整理できます。行を右クリック → Pin to top で、毎日使う部屋を、固定していない Bot や部屋より上に置いておけます(Unpin で動きのあった順に戻ります)。この固定は、このデスクトップで部屋と一緒に保存されます。右クリック → Move to section で、その部屋を自分の セクション の 1 つに入れられます。行をセクションの見出しへドラッグしても同じです。Remove from section でグループチャットのまとまりに戻ります。部屋のセクションは部屋の記録側に保存されるので(部屋にはプロファイルがありません)、セクションの一覧そのものと同じく、このデスクトップだけのものになります。
部屋の横にある Move up と Move down の矢印で、部屋同士の並び順を決められます。一度も動かしていなければ、固定した部屋が先、あとは動きのあった順という並びのままです。一度動かすと、部屋の並びはこのデスクトップに保存され、読み込み直しても残ります。新しい部屋は、固定・非固定それぞれの帯の中で、明示的に並べ替えた部屋のうしろに続きます。固定と非固定の境目をまたいで動かすことはできず、絞り込みで見えなくなった部屋が保存された並びから外れることもありません。この操作が並べ替えるのは実際のグループチャットの部屋であって、自分で作った Bot のフォルダーではありません。参加者やどのゲートウェイに属するかも変わりません。
グループの行(2〜6 体の Bot)で Open chat を押すと、その全員で調整を進める共有の部屋が開きます。
- 見えている会話は 1 本です。 全員に向けたメッセージと各参加者の返答は、届いた順に、発言者の名前と時刻を添えて読めるまま残ります。別の話題を始めても、前の返答がたたまれることはありません。Reply in thread はその話題を続けるもので、部屋の並びを変えません。Activity は状況を見るための補助的な画面であって、メッセージの代わりではありません。Bot との個別のチャットは別のままです。
- あなたのメッセージをきっかけに、参加者の発言が最大 3 巡 まで順番に回ります。@ で名指しされた Bot が応答し(誰も名指しされていなければ全員が応答します)、それぞれ短く返すか見送るかを選び、1 巡まるごと誰も話さなくなると部屋は落ち着きます。
- 参加者は
@hermesで主の Bot へ引き継げます。以前に保存した部屋でも使えます。ほかのゲートウェイにいる Bot は、端末名の付いた呼び名(たとえば@default-vera)のままです。 - Bot は
@nameで互いを引き入れ、本当に判断が要る場面では@userであなたに引き上げます。そのとき、グループの行に needs you のバッジが付きます。返事待ちの質問やコマンドの承認待ちでも、このバッジは点きます。最後の問いかけに答えたときに消えるのは問いかけの分だけで、それとは別に付いたメンションは残ります。部屋の中でのコマンドの承認は、押したその場で答えが送られます。once・session・always・denyのどれを押してもすぐ送信され、もう一段ボタンを探す必要はありません。部屋の名前を変えても問いかけはそのまま引き継がれ、部屋を解散すると、参加者からの問い合わせがあとから届いても問いかけは打ち切られます。 - 上限(1 回の送信につき 10 メッセージ、3 巡)があるので、部屋が延々と回り続けることはありません。
- 各参加者は自分の部屋のセッションを持ち続けるので、部屋の文脈もほかの会話と同じように残ります。
- すべての Bot がすべてのメッセージに返すわけではありません。 話すかどうかは各参加者が自分で決めます。付け加えることがあるときだけ返し、なければ見送ります。特定の参加者を @ で名指しすれば、その巡はその相手だけに絞られます。話しかけた相手(あるいは言うことがある相手)が発言し、ほかは静かにしている、と考えてください。
- デスクトップを閉じても部屋は動き続けます。 部屋の参加者が全員同じゲートウェイにいる場合、そのゲートウェイが消えない進行役として番の順番を受け持ちます。Hermes Desktop を閉じても(接続が切れても)話し合いの途中で部屋が止まることはなく、つなぎ直したデスクトップは部屋の記録から追いつくだけです。これが当てはまるとき、ゲートウェイの
groups.capabilitiesはdriver: trueと返します。部屋を進める働き手は 1 台の中に複数いることがあり(デスクトップがつなぐホストのゲートウェイ(hermes gateway run)と、hermes serve/hermes dashboardのバックエンドが、それぞれ 1 つずつ動かします)、そのとき部屋の進行役の権利を握っているほうが次の番を回します。参加者の部屋のセッションは自分の番の間だけ押さえられるので、この権利が働き手の間を移っても、番が断られることはありません。部屋の状態は、インストールの直下にあるshared-state.dbに置かれます。このファイルができる前に部屋を作っていたインストール(当時は直下のstate.dbに部屋を置いていました)では、更新後に最初に開いたときに、その部屋が一度だけこちらへ複製されるので、前からあるグループチャットもそのまま使えます。参加者が複数の端末に分かれている部屋は別です。各参加者の番はそれぞれ自分のゲートウェイで動き、*Bot 同士のメッセージ* で説明した接続をまたぐ運び役がそのまま使われます。
- メンションは相手を指すものとして読まれます。 やり取りの記録の中では、宛先の決まった
@botのメンション、人へ引き渡す@user、全員向けの@everyone/@allが、文中の参照として(丸い印ではなく色付きの文字で)表示されます。知らない@wordsやメールアドレスは、そのままの見た目です。Bot のメッセージにカーソルを重ねて Reply to @handle を使うと、入力欄に@handleが置かれるので、次の送信はその Bot だけに届きます(接続先にいる同名の Bot が同じ部屋にいる場合、呼び名には端末名が付きます。たとえば@reviewer-mini/@reviewer-localです)。Reply in thread はこれまでどおり、そのスレッド全体を続けます。*別の* スレッドの返信欄が開いている状態では、Reply to は主の入力欄のほうに文字を置くため、新しいスレッドが始まります。そのスレッドを続けたいときは Reply in thread を使ってください。 - 部屋は端末をまたげます。 New Group Chat は、登録済みの接続すべてを通して Bot を 2 つ選べる状態になった時点で使えます。この端末の Bot 1 つと、別のゲートウェイの Bot 1 つがあれば十分です。選択画面では、登録済みのどの接続からでも Bot を座らせられます。各参加者の応答は自分の端末で、そこにある自分の部屋のセッションの中で動きます。端末をまたいだ参加者には、部屋の中でもほかの参加者のやり取りの中でも端末のバッジ(
dixie · Mac Mini)が付き、区別のための@name-deviceという呼び名が部屋のメンションでも使えます。これにより、2 台の端末にいる同名のエージェントが混ざることはありません。デスクトップより長く続いた参加者の番(こちらが終了した、あるいは番の途中で落ちた場合)は、その参加者自身の端末で最後まで走り切ります。部屋は次に動いたときにその返答を書き込み、まだ作業中の参加者にもう一度番を振ることはありません。 - 部屋の表示は一覧と同じです。 やり取りの記録の行、「X is thinking…」の行、Activity の行は、どれも参加者のタイトルとアイコンを、その参加者が属する接続とプロファイルから引きます。Bot のタイトルや画像を変えれば、その Bot がいるすべての部屋の表示が変わり、離れた端末の参加者は自分のタイトルを保ち、別々の接続にいる同名の Bot が互いのアイコンを借りてしまうこともありません。それでも 2 人の参加者が同じに見えてしまう場合、Activity は接続の名前を後ろに添えます(
Reviewer · Mac Mini)。 - プラグインから参加者の作業を見られます。 部屋の永続的なログには
turn.startedとturn.settledが記録されます。その間に参加者がしていること(ツール、承認、流れてくる文章)は、部屋・参加者・ターンの位置を添えてon_room_member_activityフック経由でプラグインに届けられます。そのため、コミュニティ製のクライアントは Hermes の内部を読まずに、グループチャットの上にツールのカードや参加者のリアルタイムの状態を作れます。 - 参加者が部屋の外で話したことも、部屋に届きます。 各参加者の部屋のセッションは、ふつうの Hermes のセッション(
Group: <room> · <thread>というタイトル)なので、端末から再開することも、定期タスクから書き込むことも、その Bot 自身のツールから書き込むこともできます。部屋を開いたとき、そして部屋がその参加者に番を振るたびに、部屋が前に見たあとで誰かが書き足したもの(あなたの質問と、その参加者の答え)が、その参加者の名前で、そのセッションが属するスレッドに、一度だけ部屋の記録へ書き込まれます。ウィンドウを再起動しても繰り返されません。部屋自身が出した番のプロンプトとその返答が二重に書かれることはなく、エージェントの裏方の行(文脈の圧縮の記録、定期タスクの配信、委任の結果)や、それに対する参加者の反応も同じです。部屋があるセッションを見張り始めるのは、それを最初に見たときからです。その時点ですでにセッションに入っていたものは流し直されないので、2 台目のデスクトップで復元した部屋が参加者の過去のやり取りを書き直すことはありません。
Bot 同士のメッセージ
Bot は差出人を明示して互いにメッセージを送り合え、あなたはどのチャットからでも作業を引き渡せます。
- @メンション — どのチャットでも
@researcher have a look at thisのように入力すると、入力欄の@補完が相手の Bot を選ぶ手助けをします。送信時、そのメンションは現在の一覧に照らして解決され、いま話している Bot には誰を指しているのかが正確に伝わります(プロファイル名、表示名、接続をまたぐ Bot なら端末名まで)。そのあと Bot は自分の言葉でメッセージを作り、message_agentで送ります。あなたの文面がそのまま転送されることはなく、返答はその相手の名義で戻ってきます。メールアドレスや知らない@は、手を加えずにそのまま通ります。ほかの接続先の端末にいる Bot にも同じように届きます。デスクトップがその接続のソケット経由でメッセージを中継します(後述の *端末をまたぐ Bot* をご覧ください)。 - 名前を変えた Bot も呼び名が追随します — Bot に表示名を付けると(チャットのヘッダーにある鉛筆アイコン、または
hermes profile rename)、その名前で呼び出せるようになります。*Research Buddy* というタイトルの Bot は@research-buddy(および@researchbuddy)で反応し、通常のチャットでもグループの部屋でも同じです。入力欄の@補完は新しい呼び名を提示しますが、以前のプロファイル名を打っても一致し、そちらでも解決され続けます。これは主の Bot にも当てはまります。*Maia* という名前に変えると、グループの番を促す文面では@maiaとして紹介され、エージェント同士のメッセージにはMessage from 🤖 Maia (@hermes)と署名が入り、仲間はmessage_agent(target="maia")で呼べるようになります。@hermesも別名として使えるままです。 - 離れた端末の Bot も、タイトルの名前でどのチャットからでも補完されます。
@の補完には、ほかの接続先の端末にいる Bot が、デスクトップがつながった時点で並びます。先に Bots ペインを開いておく必要はありません。離れた端末のdefaultは、2 つ目の@hermesではなく、その Bot Mode でのタイトルで現れます(*CoS Bot* というタイトルの離れた default なら@cos-botです)。2 体の Bot の呼び名が同じになってしまう場合、補完は接続名まで含んだ形(@cos-bot@<connection>)を挿入し、これはその端末の Bot だけを指します。Message from 🤖 hermes (@hermes@<connection>)と署名された中継メッセージも、あなた自身の発言ではなく、エージェントからの知らせとして表示されます。 - 直接メッセージ — どの Bot Chat にも
message_agentツールが備わっています。Bot はmessage_agent(target="researcher", message="…")を呼んで仲間にメッセージを送ります。宛先に指定するのは、その仲間のプロファイル名、表示名(hermes profile renameで付けた名前や Bot Mode でのタイトル。Scribe、Dr. Fooなど)、あるいはデスクトップがその相手に付ける@の呼び名(@scribe、@dr-foo、@drfoo)です。@hermesは常に主の Bot を指します。照合はプロファイル名が先なので、別の Bot の表示名に横取りされることはありません。2 つの Bot が同じ表示名を使っている場合は、推測せずに一覧を返して断ります。ツールは相手を現在の一覧に照らして確かめ、差出人のMessage from 🤖 <friendly name> (@<handle>):という表示を自動で先頭に付け、相手の唯一の Bot Chat へ届けます。配送は 送りっぱなし です。送り手が受け取るのは*送り出した*という合図で(status: queuedとdelivery_id、それに裏で配送を担う処理のprocess_idが返ります。これはメッセージをその処理に手渡したという意味であって、届いたという意味ではありません)、送り手はそのまま自分の番を終えます。結果はその処理の完了通知が運んできます。返答か、あるいは配送の失敗です。完了通知を受け取れない環境(api_serverのセッションや、一度きり実行の仕組み)では、合図に代わりにreply_delivery: pollが付きます。この場合、送り手は自分の番を終える前にprocess(action="wait", session_id=…)で結果を取りに行きます。処理が終わったときには結果が送り手のセッションの記録にも配送の行として残るので、返答が黙って失われることはありません。完了通知は、メッセージの大きさの上限(16,000 文字)までなら返答をそのまま運びます。それより長いものは末尾だけが届き、どれだけ切り詰めたかが添えられます(残りはprocess(action="log", session_id=…)で読めます)。メッセージは本物のパラメーターとして渡るので(シェルによる解釈は一切なく、引用符も$(...)もバッククォートもそのまま届きます)、Bot はあなたの言葉を転送するのではなく、自分でメッセージを組み立てます。仲間の一覧は、各プロファイルのタイトルと説明から得た名前 と役割 を含めて、すべての Bot Chat のシステムプロンプトに入っています。だから Bot は、宛先を選ぶ前に誰が何を担当しているかを知っています。このツールが存在するのは、Bot Mode で管理されたインストールの、唯一の Bot Chat セッションの中 だけ です。通常のチャット、グループの部屋の参加者セッション、CLI のセッションからは見えません。
手元でのメッセージは、デスクトップや TUI で開いたままの Bot Chat にも届きます。別の端末から中継されたメッセージも同じです。受け取る側のバックエンドが持ち主のまま処理します。すでにある通知の巡回で永続化された受け口を読み、待機中ならその場で受け入れ、動いている番と、すでに待ち行列に入っている人からの依頼が終わるまで待ちます。queued の受領は、確実に受け付けたことを示すもので、返答が終わったという意味では ありません。届け先のプロファイルは配送 ID と受領の記録を runtime/bot_live_delivery/ の下に残し、settled が完了を示します。落ちたり取り消されたりした取り込み済みの番が自動でやり直されることはなく、いなくなった持ち主に紐づいたままの作業も、黙って走り直されるのではなく、あとから中身を確かめられる形で残ります。結果が分からない配送を送り直さないでください。ライブ配送に対応していない古いバックエンドでは、これまでどおり持ち主による断りが返ります。更新したあとは、そのバックエンドを再起動してください。
- 黙っておく — 付け加えることがない Bot は、意図的に黙るためのトークン(
[SILENT]、NO_REPLYなど)のどれかで番を終えられます。Bot Chat はその番をやり取りの記録に残しますが、画面には何も表示しません。その Bot にメッセージを送った仲間には、トークンではなく空の返答が届きます。失敗した番や、トークンに触れているだけの文章は、そのまま表示されます。
バックエンドは、プロンプトを組み立てる時点で各 Bot の唯一の Bot Chat セッションにメッセージの取り決めを自動で教えます。仲間が CLI から画面なしで開いた場合も同様です。この取り決めの部分が入るのは唯一の Bot Chat だけで、通常のセッションとあなたの SOUL.md には手を付けません。この動作は config.yaml の agent.bot_mode_protocol で制御します(既定は有効)。
agent:
bot_mode_protocol: true # inject the bot-to-bot messaging protocol into canonical Bot Chatsチャットが Bot Chat になる条件
agent.bot_mode_protocol は大元のスイッチにすぎません。取り決めの部分や message_agent の道具が差し込まれるには、さらに 2 つの条件が要ります。デスクトップ版では、Bots ペインが Bot を作った時点で両方とも満たしてくれます。
- セッションのタイトルがちょうど
Bot Chatであること。 このタイトルそのものが、唯一のチャットの目印です(デスクトップのプラグインの createCanonicalChat が使うのも、hermes -p <bot> chat -c "Bot Chat"が再開するのもこれです)。ほかのタイトルや、タイトルのない使い捨てのセッションには、取り決めの部分も道具も付きません。 - そのインストール先のどれか 1 つのプロファイルが、
profile.yamlにui_meta: { hermes-bots: … }の塊を持っていること。 これは、デスクトップのプラグインが自分の持ち物の Bot すべてに書き込む「Bot Mode の管理下」という目印です。判定はすべてのプロファイルを見て回るので、1 つ付いていればそのインストール全体に付いているとみなされます。これを書き込む CLI のコマンドはありません。
そうすると何が起きるか。デスクトップアプリのない、画面のないインストール先(ゲートウェイと Telegram だけ、など)では、どちらの目印も書かれないので、説明の上ではスイッチが入っていても message_agent に手が届きません。ボット同士はメッセージの基盤の上で問題なくやり取りできますが、エージェント側の message_agent という道具が現れないのです。画面のない環境で使えるようにするには、2 つの条件を手作業で満たします。
# the canonical forever-chat, created once per Bot (later runs resume it)
hermes -p <bot> chat -c "Bot Chat" --create-if-missing# ~/.hermes/profiles/<any-bot>/profile.yaml — an empty block is enough to mark the install
ui_meta:
hermes-bots: {}その Bot Chat の次の番から、仲間の一覧、取り決めの部分、message_agent がすべて有効になります。端末だけの機械で hermes -p <bot> chat を使う場合も同じです。
失敗した番は安全にやり直します
手元での 1 回きりの配送は、動いているセッションを断る際のコードを、人が読む文面とは 別に保ちます。SESSION_NOT_OWNED は target_busy になります。読み取れない調整用の 記録が、別の持ち主がいるかのように取り違えられることはありません。このコードの目印を 持たない古い手元の CLI では、これまでどおりの断り文句が使われます。
配送に失敗した番は最大 1 回だけ、しかもやり直しに意味がある場合にだけ再実行されます。一時的な失敗(相手の実行環境が落ちている、配送のタイムアウト、プロバイダーの流量制限やサーバーエラー)は、同じ Bot Chat セッションをそのまま実行し直します。文脈があふれた場合も同じセッションを実行し直しますが、このときは標準の文脈圧縮を通して閾値を超えたやり取りを縮めてからモデルを呼ぶので、元は収まらなかったものがやり直しでは収まります。認証、利用枠、設定に起因する失敗は自動でやり直しません。2 回目でも直らず、利用枠を無駄に消費するだけなので、失敗はその場で表に出します。やり直した番が新しいセッションを始めることはないので、Bot Chat の履歴と文脈はそのまま保たれます。やり直しでは、失敗した試行がすでに Bot Chat へ書き込んだメッセージを引き継ぐので、書き足しにはならず、受け取った側のやり取りにはその個別メッセージがちょうど 1 通だけ残ります。
届け先にデスクトップや TUI の持ち主が動いていない場合、手元の配送は、表示を出さない CLI の番を使ってそのプロファイルの唯一の Bot Chat を開きます。このとき配送の仕組みは、送り手の実行環境の Python インタープリターの隣にある Hermes の入口を優先します。そのため、その入口が存在する限り、 サービスの PATH 上にある無関係な、あるいは古い hermes が先に使われることはありません。--in ~ で作業ディレクトリを選び、 明示した Bot Chat のタイトルは、届け先のプロファイルのセッションデータベースの中で解決されます。
配送に失敗したとき: 種類の付いた理由
Bot の番や中継の配送が失敗すると、人が読むエラー文と一緒に、機械が読める reason コードが最後まで運ばれます。相手側のゲートウェイが失敗を分類し(provider_auth_or_access、provider_quota_limit、provider_rate_limit、provider_server_error、context_overflow、missing_config、model_unavailable、runtime_offline、queued_expired、delivery_timeout、target_busy、unknown)、デスクトップがそれを転送し、送り手のエージェントの完了通知にはエラー文の前に [reason: <code>] が付きます。呼び出した側のエージェントは、プロバイダーの文面を解析する代わりに、このコードで処理を分けられます(「入り直してください」なのか「あとで再試行」なのか)。デスクトップの要対応バッジも同じコードを使います。
接続した端末をまたぐメッセージ(デスクトップの中継)
Settings → Connections に登録したゲートウェイは、手元のもの、URL 指定の離れたもの、SSH 経由、Hermes Cloud、docker のいずれであっても、デスクトップが開いたまま保つ常設の線です。Bot Mode はその線をメッセージの配送に自動で使います。追加の設定は要りません。
- 一覧は自動で伝わります。 デスクトップが動いている間、接続している各ゲートウェイに対して、*ほかの* 接続にどんなエージェントがいるかを定期的に伝えます。すると各 Bot Chat の仲間の一覧にそれらが並び(「Teammates on OTHER connected machines」)、名前、役割、どの端末にいるかが分かります。エージェントが増えたり消えたり名前が変わったりすると、一覧も更新されます(capability epoch)。
message_agentはそこへ直接届きます。 手元のノート PC にいる Bot は、message_agent(target="moxie", …)でクラウドのエージェントに、手元の仲間とまったく同じようにメッセージを送れます。同じ呼び名が複数の端末にある場合はtarget="moxie@<connection>"で区別します(ツールのエラーが、正確な書き方を Bot に伝えます)。仲間の一覧には、Settings → Connections で付けた端末の名前がそのまま並ぶので、Bot は素っ気ない接続の ID ではなく@moxie on Homelabとして読みます。配送はデスクトップを経由します。送り手側のゲートウェイがメッセージを待ち行列に入れ、デスクトップが相手の接続のゲートウェイへ中継し、相手の Bot が自分の唯一の Bot Chat で 1 回動き(そのチャットがデスクトップで開いているときは、そのチャットの次の番として動きます)、返答は手元の個別メッセージと同じ完了通知として送り手に戻ります(返答を待つ処理は Hermes の入口なので、Bot が 1 回だけ返事をする番の既定であるapprovals.single_query_mode: denyの下で始まります。開いているチャットがライブ配送の持ち時間の中で答えなかった場合は、そのチャットに積まれたという報告になります。送り直さないでください)。別々の Bot 宛のメッセージは並行して配送されるので、ある Bot の長い番がほかの Bot 宛の便を遅らせる(あるいはbot_mode.envelope_ttl_secondsを過ぎるまで待たせる)ことはありません。*同じ* Bot 宛のメッセージは、1 回に 1 つの番ずつ、順番どおりに届きます。- デスクトップが運び役です。 接続をまたぐ配送は、両方の接続を知っているデスクトップが動いている間に働きます(ソケットと認証情報を持っているのはデスクトップで、ゲートウェイ同士が互いの認証情報を見ることはありません)。配送の途中でデスクトップが閉じられた場合、送り手の Bot は返答が届かなかったと知らされ、宙ぶらりんにはなりません。デスクトップが受け取ったものの相手に渡せなかったメッセージ(その間に接続が切れた場合)は、次の取り出しのときにもう一度差し出されます。ただし 1 回だけで、しかもデスクトップ自身の配送の締め切り(およそ 26 分)を返答のないまま過ぎたあとに限られるので、時間はかかっていても生きている番が二重に配送されることはありません。送り手は、この 2 回目の配送が終わるまで待ち続けます(全体でおよそ 52 分です)。それでも返答が得られない場合、送り手には
delivery_timeoutという理由が伝わります。差し出し直されたメッセージが取り出しを待っている間も、bot_mode.envelope_ttl_secondsは、待ち行列に入れたばかりのメッセージとまったく同じように働きます。そして、あるメッセージに対して最初に記録された返答が、そのまま正式なものになります。デスクトップを挟まず、端末同士で常時メッセージをやり取りしたい場合は、後述のピア(hermes peer)を登録してください。2 つの経路は共存できます。 - 離れた端末の
defaultは、そのタイトルで呼びます。 どの端末でもdefaultは@hermesなので、離れた端末の default は代わりに Bot Mode でのタイトルで提示され、その名前で届きます(*CoS Bot* というタイトルの離れたdefaultなら@cos-bot、タイトルがなければhermes@<connection>です)。そこから送られた個別メッセージにも、あなた自身の default を指してしまう素っ気ない@hermesではなく、返信にそのまま使えるこの形の署名が付きます。 - 10 分の上限が区切るのは相手の番であって、その先の引き渡しではありません。 中継されたメッセージは、相手の Bot に番を終えるための 10 分を与えます。その番の中で相手がさらに仲間へメッセージを送った場合、配送の処理はそのあとも生き続け(
terminal.oneshot_completion_wait_secondsが上限です)、仲間の返答がその Bot Chat に届くようにします(間に合えば、それが送り手へ返される答えになります)。この待ち時間が上限に数えられることはありません。終わった番はdelivery_timeoutではなく、その答えとともに送り手へ報告され、引き渡しのほうは最後まで進みます。
端末をまたいで Bot 発のメッセージを送る(hermes peer)
ある端末の Bot は、デスクトップを一切挟まずに 別の端末のゲートウェイ にいる Bot へメッセージを送れます。相手のゲートウェイを *ピア* として登録します(API サーバーの URL と API_SERVER_KEY)。
hermes peer add spark --url http://spark.lan:8377 --key <API_SERVER_KEY>
hermes peer list
hermes peer dm spark < ~/.hermes/cache/scratch/dm.txt # message body from a file (nothing shell-interpreted)
hermes peer dm spark/researcher < ~/.hermes/cache/scratch/dm.txt # named profile on a multiplexed peer
hermes peer run spark --idempotency-key ticket-123 < ~/.hermes/cache/scratch/long-task.txt
hermes peer status spark run_abc123
hermes peer stop spark run_abc123hermes peer dm は、相手のエージェントの唯一の Bot Chat へ、そのピアの既存の API サーバー経由でメッセージを届け、そこで 1 回だけエージェントを動かし、返答を標準出力に表示します。手元で使う hermes -p <bot> chat の、端末をまたいだ双子のようなコマンドです。
peer dm は短い問い合わせや受け取り確認にだけ使ってください。番が終わるまで HTTP 接続を 1 本占有するからです。ピアがメッセージを受け取ったあと、番がその接続より長く続いた場合、 メッセージはすでにピアの Bot Chat に入っていて、番もそちらで走り続けています。そこでコマンドは ピアに届かなかったと報告するのではなく、そのとおりのことを伝えます。送り直すと番が二重に走るからです。 接続の段階での時間切れは、これまでどおりピアに届かなかったという報告になります。ピアの Bot Chat が そちらのデスクトップで開いている場合、メッセージは開いているチャットに渡され、そのチャットの次の番として 走ります。見ている人にはその様子が見え、返答はこの呼び出しにそのまま返ります(流し込みの経路でも同じで、 その番の唯一の完了イベントとして返ります)。その番が 5 分たっても終わらないときは、peer dm は メッセージが失われたのではなく、そのチャットに積まれたと報告します。時間のかかる番には peer run を使うと、すぐに run_id が返ります。あとは peer status で状況を確かめます。ピアの Bot Chat がそちらのデスクトップで 開いている場合、この実行はそのチャットの次の番になり、状況もそのチャット自身の受領に従います。この実行は 唯一の Bot Chat のやり取りを引き継ぎ、--idempotency-key を一定にしておけば、 やり直しても新しい作業を重ねて始めるのではなく元の実行が返ります。peer stop にその実行 ID をそのまま渡せば、別の番に当たることなく中断できます。
ピアを登録すると、すべての Bot Chat に教えられるメッセージの取り決め(agent.bot_mode_protocol)にピアの一覧が自動で含まれ、message_agent はピア宛の指定をそのまま受け付けます。message_agent(target="spark/researcher", …) のように書き、ピアの主エージェント宛なら target="spark" です。つまり Bot たちは自分で学びます — ほかの端末に仲間がいることと、そこへの届け方を。ピアを登録したり外したりすると、各 Bot Chat の取り決めは次のメッセージのときに更新されます(capability epoch)。
必要な条件は、ピア側の端末が api_server のゲートウェイ基盤を強い API_SERVER_KEY とともに動かしていることです。到達できるかどうかは、そちらのネットワーク次第です(LAN、Tailscale、VPN)。この鍵は認証情報なので、~/.hermes/.env に HERMES_PEER_<NAME>_KEY として置かれます。ピアの名前と URL は config.yaml の bot_peers の下に置かれます。
部屋の主導権を引き継ぐ
主導権の引き取りは、運用者が手で行う 復旧の手順 であって、一瞬で切り替わる 仕組みではありません。すでにある JSON-RPC の groups.promote と groups.demote を、 それぞれ適切なゲートウェイに対して使います。groups.peer.promote や groups.peer.demote といったものはありません。手元のゲートウェイが受け付ける 一覧は groups.capabilities で確かめられます。
- 複製がどこまで届いているかを確かめます。 引き継ぐ側のゲートウェイで
groups.replica_state を {"room_id":"ROOM_ID"} とともに見て、last_seq と latest_seq を見比べます。計画的な引き継ぎでは、複製が完全であることを条件に してください。昇格そのものは、この到達具合を調べません。groups.replicate は groups.log が返したページを取り込んだあとに caught_up と報告しますが、ピアを 登録しただけでは、引き継ぐ側が部屋の履歴を持っている証拠にはなりません。 caught_up の状態は最後に複製したページのことを言っているだけで、古い書き手が止まった 証拠でも、新しい出来事がもう無い証拠でもありません。計画的な移行なら、書き手を 静めて、最後の位置まで複製し、そのうえで止めた状態を保ちます。障害からの復旧なら、 複製に届かなかった履歴があることを見込んでおいてください。
- 古い書き手を止めた状態でだけ昇格させます。 引き継ぐ側で次を実行します。
{"jsonrpc":"2.0","id":1,"method":"groups.promote","params":{"room_id":"ROOM_ID","confirm":true,"reason":"planned-handover"}} room_id と confirm: true は必須で、reason は省略でき、既定では authority-unreachable になります。この確認は、前の主導権が書き込めないことを こちらが表明するものであって、自動で止めてほしいという依頼では ありません。 確認がないと、この呼び出しは 4118 のエラーを返します。成功すると、 authority_gateway_id と authority_epoch(複製した epoch に 1 を足したもの)が 返ります。
- 元に戻す前に、古い主導権を降格させます。 部屋へ書き込む普段の処理は止めた
ままにして、古いゲートウェイ側で復旧用の限られた接続からこの RPC を実行します。 例に書いてあるゲートウェイ ID と epoch は、昇格が成功したときに返ってきた値に 置き換えてください。
{"jsonrpc":"2.0","id":2,"method":"groups.demote","params":{"room_id":"ROOM_ID","observed_gateway_id":"NEW_GATEWAY_ID","observed_epoch":2}} 3 つの引数はすべて必須です。先の epoch を当てずっぽうで書かないでください。 降格には、より新しい主導権があるという証拠が要るのであって、こしらえた値では ありません。これは authority.lost として記録され、見えている系統をそのまま 受け入れます。同じ系統を繰り返し渡しても結果は変わりません。古いホストに 手が届かない場合は、止めたままにして、普段の書き手を戻す前にこの手順を 済ませてください。
- 確かめてから、つなぎ直します。 両方のゲートウェイで
groups.stateを読み、
room.authority_gateway_id と room.authority_epoch を昇格の結果と見比べます。 古い主導権からの送信は拒まれるはずです。接続先は引き継いだ側に向けてください。 降格が止めるのは書き込みだけです。履歴を混ぜ合わせることも、古い主導権の 保管場所を自動で同期する複製に変えることもありません。
古いゲートウェイが書き込める状態のまま昇格させると、2 つの state.db がどちらも メッセージを受け付け、履歴が枝分かれしていきます。引き継いだ側の epoch のほうが 大きくても、離れた場所にある古い書き手が止まるわけではありませんし、epoch が 同じでなければ枝分かれが起きない、ということもありません。すでに履歴が分かれて しまっている場合は、書き手を止めて両方の履歴を復旧用に保存してください。昇格や 降格や再生が混ぜ合わせてくれる、とは考えないことです。
端末をまたぐ Bot
Settings → Connections に複数のバックエンドを登録すると(手元の実行環境、離れたゲートウェイ、SSH 接続先のホスト、Hermes Cloud の環境など)、一覧には接続している すべての 場所の Bot が、常に表示され続けます。SSH の接続先は、相手の端末で何かを起動することなく内容を把握します。一時的に届かない端末も、消えてしまうのではなく最後に分かっていた行が残ります。同じプロファイル名が複数の場所にある場合、呼び名は @name-device の形で区別されます(たとえば @research-homelab)。Bot のチャット、セッション、記憶、定期タスクは、そのプロファイルを持っている端末側にあります。
接続先の Bot をクリックしても、ウィンドウがその端末へ移ることは ありません。いまのチャットにいたまま @mention で呼びかけ、グループチャットに座らせ、Create on の選択欄で直接その端末に新しいエージェントを作れます。クラウドと手元のエージェントは、こうして 1 つの一覧を共有します。Hermes Cloud の環境とデスクトップを(たとえば Tailscale や SSH 経由で)登録すれば、そこにいる Bot 同士がメッセージを送り合い、同じ部屋に座れます。それぞれの作業は自分の端末で動きます。それらの端末をまたぐ Bot 同士の個別メッセージは、デスクトップの中継を自動的に通ります(上の *接続した端末をまたぐメッセージ* をご覧ください)。
複数接続についての詳しい案内は デスクトップを複数の Hermes 環境につなぐ をご覧ください。
ローカルの Bot とゲートウェイ(同時に動く Bot の数)
デスクトップは、Bot ごとにバックエンドを動かすわけではありません。ホストごとに 1 つのゲートウェイのプロセスが、ローカルのすべてのプロファイルのセッションを受け持ちます。ローカルの Bot を開くと、デスクトップはそのプロファイルに対して hermes gateway ensure --json を実行します。これは動いているゲートウェイにつなぐか、そのプロファイルを受け持つものがまだなければゲートウェイを起動します。そのうえで、使い捨ての通行証を使って WebSocket(/api/ws)でつなぎます。デスクトップ側にバックエンドの枠はなく、同時に待機させておける Bot の数を決める設定も、使われていないものを片づける仕組みもありません。別の Bot を開くときに空きを待つことはなく、別の Bot の履歴を読んでも、同じゲートウェイへのリクエストが 1 つ増えるだけです。
ゲートウェイがいつまで動くかは、デスクトップのウィンドウとは関係ありません。ウィンドウを閉じても、デスクトップを終了しても、接続を忘れるだけでゲートウェイは止まりません。メッセージングの Bot、定型の処理、進行中の番はそのまま動き続け、次に開いたときにデスクトップがつなぎ直します。止めたいときは hermes gateway stop で明示的に止めてください。デスクトップの裏でゲートウェイが再起動した場合(更新、異常終了、hermes gateway stop のあとでもう一度開いたときなど)、デスクトップは gateway ensure を一度だけ実行し直してつなぎ直します。gateway.standalone: true を付けたプロファイルは自分専用のゲートウェイを持ちますが、デスクトップは同じやり方でそこにつなぎます。
Settings → Connections にあるリモートのゲートウェイ、SSH のホスト、Hermes Cloud のインスタンスは、それぞれ自前のプロセスを持つ別のホストです。そこにある Bot はその機械で動き(上の *端末をまたぐ Bot* を参照)、このホストのゲートウェイでは動きません。
無効にする
Bot Mode は同梱のデスクトッププラグインです。Capabilities → Plugins → Bots で Desktop のスイッチを切ると、一覧、Routines ペイン、入力欄の中間処理がその場で解除されます。再起動は要りません。どちらの状態でも、プロファイル、セッション、cron ジョブには手が付きません。Bot Mode があなたのデータを所有することはなく、それを表示しているだけです。
唯一の Bot Chat を通常のサイドバーのセッション一覧から隠す設定もあります。こうすると、Bots ペインの中だけに現れます。(本体の「セッションを隠す」フラグを使います。古いゲートウェイでは、そのまま表示されたままになります。)
CLI での同じ操作
Bot はプロファイルなので、すべてに端末からの同じ操作があります。
| Bot Mode では | シェルからは |
|---|---|
| Bot と話す | hermes -p <bot> chat |
| Bot のファイル、スキル、記憶 | ~/.hermes/profiles/<bot>/ |
| Routines | hermes cron list([bot:<name>] … という名前のジョブ) |
| プロファイルの作成・確認 | hermes profile create、hermes profile list |
土台となる仕組みについては プロファイル、CLI の全項目については プロファイルのコマンド をご覧ください。