コンテンツにスキップ

Discord Thread で ACP エージェントを動かす:OpenClaw の新しいアーキテクチャ

チャットプラットフォームでエージェントを動かす際、メッセージが重複したり、セッションの状態がいつの間にか消えてしまったりすることはありませんか?スレッドの状態とエージェントの実行状態が同期していないと、開発者にとってもユーザーにとっても大きなストレスになります。

OpenClaw では、これらの課題を解決するために ACP(Agent Control Plane)エージェントを Discord などのスレッドに直接紐付ける「Thread Bound Agents」の仕組みを導入します。

  • Discord(スレッド機能が利用可能なチャンネル)
  • OpenClaw Gateway
  • acpx バックエンドプラグイン
  • SQLite(ステート管理用)

ACP セッションをスレッドで動かすための最小ステップは以下の通りです。

  1. セッションの開始: /focus コマンドを使用して、ACP セッションを特定のスレッドにバインドします。
  2. ルーティング: スレッド内でユーザーがメッセージを送信すると、OpenClaw Core がバインドされた ACP セッションを特定し、自動的にルーティングします。
  3. ストリーミング: エージェントの出力は Webhook を通じて、同じスレッドのペルソナとしてリアルタイムに書き込まれます。
  4. クリーンアップ: セッションが終了すると、/unfocus やスレッドのアーカイブなどのイベントをトリガーに、リソースが適切に解放されます。

OpenClaw Core は ACP のコントロールプレーン(制御層)に集中し、実際の実行(ランタイム)はプラグインとして切り離すハイブリッドアーキテクチャを採用しています。

セッションと実行のステータス管理

Section titled “セッションと実行のステータス管理”

すべての ACP セッションは、以下の明示的なライフサイクル状態を持ちます。

  • Session 状態: creating, idle, running, cancelling, closed, error
  • Run 状態: queued, running, completed, failed, cancelled

ACP の状態管理には、OpenClaw のステートディレクトリ配下にある専用の SQLite(WAL モード)を使用します。イベントを追記型(Append-only)で保存することで、クラッシュからの復旧や決定論的なデリバリーを可能にします。

  • メッセージが重複して出力される: コマンドの再試行にべき等性(Idempotency Key)を導入しています。これにより、ネットワークの瞬断などで再送が発生しても、Discord への二重出力を防ぎます。
  • メタデータの同期が取れない: 移行期間中は SessionEntry.acp を互換性のために維持しますが、SQLite 側のコントロールプレーン DB を Source of Truth(信頼できる唯一の情報源)として参照してください。
  • ルーティングが正しく行われない: 不正確なセッションへの配送を防ぐため、Fail-closed なルーティングチェックを実装しています。バインドが確認できない場合は、メインの応答パスへ流さずに遮断します。
  • クラッシュ後のセッション復旧: SQLite の WAL モードとイベントログにより、システム再起動時にも Startup Restore 機能が働き、永続的なバインド状態を復元します。

具体的な設定や導入方法で困ったときは、AI Setup Assistant でいつでも質問してください。

LLMを活用したエージェントを開発していると、セッションの管理に頭を悩ませることがよくあります。プロンプトを投げるたびにプロセスが立ち上がるのを待たされたり、接続が切れた際に状態が分からなくなったりするのは、開発者にとって共通の痛みです。

OpenClawのACP(Agent Control Protocol)は、こうした課題を解決するために設計されました。プロセスのライフサイクルを適切に管理し、クラッシュからの回復やメッセージの重複防止を確実に行うための、堅実なアーキテクチャを見ていきましょう。

このアーキテクチャを理解し実装するには、以下のコンポーネントが必要です。

  • OpenClaw Core
  • Plugin backend (acpx 実装)
  • ACP SQLite database (WAL mode)

ACPの実行環境を構築するための最小経路は、AcpRuntime インターフェースを理解することから始まります。ルーティングのコードが特定の CLI 詳細に依存しないよう、この共通のコントラクトが定義されています。

export type AcpRuntimePromptMode = "prompt" | "steer";
export type AcpRuntimeHandle = {
sessionKey: string;
backend: string;
runtimeSessionName: string;
};
export type AcpRuntimeEvent =
| { type: "text_delta"; stream: "output" | "thought"; text: string }
| { type: "tool_call"; name: string; argumentsText: string }
| { type: "done"; usage?: Record<string, number> }
| { type: "error"; code: string; message: string; retryable?: boolean };
export interface AcpRuntime {
ensureSession(input: {
sessionKey: string;
agent: string;
mode: "persistent" | "oneshot";
cwd?: string;
env?: Record<string, string>;
idempotencyKey: string;
}): Promise<AcpRuntimeHandle>;
submit(input: {
handle: AcpRuntimeHandle;
text: string;
mode: AcpRuntimePromptMode;
idempotencyKey: string;
}): Promise<{ runtimeRunId: string }>;
stream(input: {
handle: AcpRuntimeHandle;
runtimeRunId: string;
onEvent: (event: AcpRuntimeEvent) => Promise<void> | void;
signal?: AbortSignal;
}): Promise<void>;
cancel(input: {
handle: AcpRuntimeHandle;
runtimeRunId?: string;
reason?: string;
idempotencyKey: string;
}): Promise<void>;
close(input: { handle: AcpRuntimeHandle; reason: string; idempotencyKey: string }): Promise<void>;
health?(): Promise<{ ok: boolean; details?: string }>;
}

ACPの機能は、OpenClawの Core と Plugin backend に明確に分離されています。

  • Reply pipeline における ACP session-mode のディスパッチ分岐
  • 親スレッドと子スレッドの重複を避けるための配信調停(delivery arbitration)
  • ACP control-plane の永続化(移行時の SessionEntry.acp 互換性プロジェクションを含む)
  • セッションのリセットや削除に紐付いた、ライフサイクルの unbind およびランタイムの detach セマンティクス
  • ACP runtime worker の監視
  • acpx プロセスの呼び出しとイベントのパース
  • ACP コマンドハンドラー(/acp ...)とオペレーター向けの UX
  • バックエンド固有の設定デフォルト値と診断機能

状態の管理と実行の分離が、このアーキテクチャの鍵です。

  • 1つの Gateway プロセスが ACP のオーケストレーション状態を所有します。
  • ACP の実行は、acpx バックエンドを通じて監視下にある子プロセスで行われます。
  • プロセスの戦略は、メッセージごとではなく、アクティブな ACP セッションキーごとに長時間生存(long lived)させます。

これにより、プロンプトごとの起動コストを回避し、キャンセルや再接続のセマンティクスを安定させています。

コントロールプレーンのデータモデル

Section titled “コントロールプレーンのデータモデル”

長期的な信頼できる情報源(source-of-truth)として、トランザクションの更新とクラッシュからの回復に優れた ACP 専用の SQLite データベース(WAL モード)を使用します。

  • acp_sessions: セッションの状態、バックエンド、エージェント情報、カレントディレクトリなど
  • acp_runs: 各実行の ID、セッションキー、状態、冪等性キー、エラー情報
  • acp_bindings: スレッド、チャンネル、アカウントとセッションの紐付け
  • acp_events: 実行中に発生したイベントのシーケンスとペイロード
  • acp_delivery_checkpoint: 配信済みのイベントシーケンスと Discord メッセージ ID
  • acp_idempotency: スコープごとの冪等性キーと実行結果
export type AcpSessionMeta = {
backend: string;
agent: string;
runtimeSessionName: string;
mode: "persistent" | "oneshot";
cwd?: string;
state: "idle" | "running" | "error";
lastActivityAt: number;
lastError?: string;
};

プロセス ID やソケットはメモリ上のみで保持されますが、ライフサイクルや実行ステータスは ACP DB に保存されます。Gateway が停止しても、DB のチェックポイントから再開できる仕組みです。

まずスレッドのバインディングを確認します。ターゲットが ACP セッションであれば、通常の getReplyFromConfig ではなく ACP runtime ブランチへルーティングします。/acp steer コマンドが使用された場合は、mode: "steer" が適用されます。

ACP イベントストリームは OpenClaw の Reply chunk に正規化されます。配信先は既存のバインドパスを通じて解決されます。バインドされたスレッドがアクティブな間は、親チャンネルの完了通知は抑制されます。

Discord のレート制限を考慮し、ストリーミング出力は結合ウィンドウを用いて調整されます。設定可能な最小間隔と最大バイト数に基づき、完了時または失敗時に最終メッセージが送信されます。

状態遷移とトランザクション境界

Section titled “状態遷移とトランザクション境界”

不完全な成功を防ぐため、以下のトランザクション境界を設けています。

  • Spawn トランザクション: セッション行の作成、バインディングの更新、初期実行行の追加
  • Close トランザクション: セッションのクローズ、バインディングの削除・期限切れ設定、終了イベントの書き込み
  • Cancel トランザクション: ターゲットの実行をキャンセル中またはキャンセル済みにマーク
  • Session: creating -> idle -> running -> idle(エラー時は error へ)
  • Run: queued -> running -> completed(失敗やキャンセル時は failed または cancelled へ)

セッションごとのアクターモデル

Section titled “セッションごとのアクターモデル”

AcpSessionManager は、ACP セッションキーごとに1つのアクターを実行します。

  • アクターのメールボックスが submit, cancel, close, stream の副作用をシリアライズ(順序化)します。
  • アクターがランタイムハンドルの復元とアダプタープロセスのライフサイクルを管理します。
  • Discord へ配信する前に、アクターがイベントを順序通り(seq)に書き込みます。
  • 配信が成功した後、アクターが配信チェックポイントを更新します。

これにより、ターンの交差によるレースコンディションや、スレッド出力の重複、順序の入れ替わりを防いでいます。

すべての外部アクション(spawn, prompt/steer, cancel, close)には冪等性キーが必要です。リトライ時にはチェックポイントから再開し、配信済みのチャンクを再送することはありません。

Gateway の起動時には、ターミナル状態(完了)にないセッションを読み込み、最初のアクションが発生したタイミングでアクターを遅延再生成します。もし実行中のランにハートビートがない場合は、失敗としてマークするかアダプター経由で復旧を試みます。

運用の安全性を高めるため、以下の制御を導入しています。

  • TTL ポリシー: グローバル設定、Discord スレッドの期限、ランタイムオーナーの期限のうち、最小のものが適用されます。
  • 安全管理: エージェント名の許可リスト、ワークスペースのルート制限、環境変数のパススルー許可リスト、アカウントごとの最大セッション数制限。

不適切なバインディングが残っている場合、OpenClaw はサイレントに通常の LLM パスへ流すことはせず、明示的なエラーメッセージとともに安全に失敗させます。

  • ステールなバインディング: セッションが消えているのにバインディングだけが残っている場合、自動的なアンバインドが行われるか、オペレーターによる検証が必要になります。
  • ランタイムのクラッシュ: アダプターがクラッシュした場合は、バックオフ制御に基づいた再起動が行われます。

詳細な設定やセットアップについては、AI Setup Assistant で質問してみてください。

エージェントの実行環境やセッション管理の設定は、時に複雑に感じることがあります。「どのバックエンドを使うべきか」「セッションのタイムアウトはどう設定するか」といった悩みは、開発者にとって共通の課題です。

ACP(Agent Control Plane)の動作を細かく制御するための設定項目を整理しました。これらを適切に設定することで、環境に合わせた最適なエージェント運用が可能になります。

  • ACP の設定ファイルへのアクセス
  • サポートされているバックエンド(デフォルトは acpx)

まずは ACP を有効化し、基本的なバックエンドを指定することから始めましょう。

  1. acp.enabled を true に設定します。
  2. acp.backend で使用するバックエンド(例: acpx)を指定します。

ACP の挙動を決定する主要な設定キーは以下の通りです。

  • acp.enabled: ACP 自体の有効・無効を切り替えます。
  • acp.dispatch.enabled: ACP ルーティングの独立したキルスイッチとして機能します。
  • acp.backend: 使用するバックエンドを指定します(デフォルトは acpx)。
  • acp.defaultAgent: デフォルトで使用されるエージェントを設定します。
  • acp.allowedAgents[]: 許可されたエージェントのリストを定義します。
  • acp.maxConcurrentSessions: 同時に実行可能な最大セッション数を制限します。
  • acp.stream.coalesceIdleMs: ストリームのアイドル時間を結合する際のミリ秒単位の待機時間です。
  • acp.stream.maxChunkChars: ストリームの 1 チャンクあたりの最大文字数を指定します。
  • acp.runtime.ttlMinutes: ランタイムの生存時間を分単位で設定します。
  • acp.controlPlane.store: 使用するストアの種類を指定します(デフォルトは sqlite)。
  • acp.controlPlane.storePath: ストアの保存先パスを設定します。
  • acp.controlPlane.recovery.eagerActors: リカバリ時にアクターを即座に起動するかどうかを制御します。
  • acp.controlPlane.recovery.reconcileRunningAfterMs: 実行中の状態を再調整するまでの待機時間をミリ秒で指定します。
  • acp.controlPlane.checkpoint.flushEveryEvents: チェックポイントを書き出すイベントの間隔を設定します。
  • acp.controlPlane.checkpoint.flushEveryMs: チェックポイントを書き出す時間の間隔をミリ秒で設定します。
  • acp.idempotency.ttlHours: べき等性(Idempotency)を保持する時間を時間単位で設定します。
  • channels.discord.threadBindings.spawnAcpSessions: Discord スレッドとのバインディングにおいて ACP セッションを生成するかどうかを指定します。

acpx プラグインセクションでは、バックエンドに関するより詳細な制御が可能です。

  • backend command/path overrides: バックエンドの実行コマンドやパスを上書きします。
  • backend env allowlist: バックエンドに渡す環境変数の許可リストを定義します。
  • backend per-agent presets: エージェントごとのプリセット設定を管理します。
  • backend startup/stop timeouts: バックエンドの起動および停止時のタイムアウト時間を設定します。
  • backend max inflight runs per session: 1 セッションあたりに許容される最大実行数を制限します。

設定に関する不明点や、期待通りに動作しない場合は、AI Setup Assistant で詳細なガイドを確認してください。

複雑なステートを持つエージェントセッションを管理するのは、開発者にとって常に頭の痛い問題です。セッションの不整合や、不透明な実行状態、そして再起動時のリカバリ処理など、信頼性を担保するために考慮すべき点は多岐にわたります。

こうした課題を解決するために、新しい ACP(Agent Control Plane)の実装が進められています。本ガイドでは、システムの整合性を維持しつつ、拡張性の高いエージェント環境を構築するための具体的な仕様を解説します。

実装を開始する前に、以下のコンポーネントがソースコード内に用意されていることを確認してください。

  • src/acp/control-plane 内の新規モジュール群
  • src/config/sessions/types.ts(SessionEntry の定義)
  • acpx ランタイムプラグイン(backend として使用する場合)
  • SQLite 環境(store.ts での管理用)

最短で ACP を稼働させるための手順は以下の通りです。

  1. コントロールプレーンの配置: src/acp/control-plane/ に manager.ts や store.ts などのコアモジュールを実装します。
  2. バックエンドの登録: src/acp/runtime/registry.ts を使用して、acpx などのランタイムを登録します。
  3. ディスパッチの設定: src/auto-reply/reply/dispatch-from-config.ts を修正し、AcpSessionManager.submit を呼び出すように変更します。
  4. フラグの有効化: 構成ファイルで acp.enabled および acp.dispatch.enabled を true に設定します。

コントロールプレーンモジュール

Section titled “コントロールプレーンモジュール”

Core に以下の ACP 専用モジュールを追加します。

  • src/acp/control-plane/manager.ts: ACP actor、ライフサイクル遷移、コマンドのシリアライズを管理
  • src/acp/control-plane/store.ts: SQLite スキーマ管理、トランザクション、クエリヘルパー
  • src/acp/control-plane/events.ts: 型定義された ACP イベント定義とシリアライズ
  • src/acp/control-plane/checkpoint.ts: 永続的な配信チェックポイントとリプレイカーソル
  • src/acp/control-plane/idempotency.ts: べき等キーの予約とレスポンスのリプレイ
  • src/acp/control-plane/recovery.ts: 起動時の整合性チェックと actor の再ハイドレート計画

遵守すべき不変条件(Invariants)

Section titled “遵守すべき不変条件(Invariants)”

コード内で以下の条件を必ず強制してください。

  • ACP セッションの作成とスレッドバインドは原子的に行う(単一トランザクション)
  • 1 つの ACP セッション actor に対して、一度に実行できる run は最大 1 つとする
  • イベントの seq は run ごとに厳密に増加させる
  • 配信チェックポイントは、最後にコミットされたイベントを超えて進めない
  • べき等リプレイでは、重複するコマンドキーに対して前回の成功ペイロードを返す
  • 古い、または欠落している ACP メタデータは、通常の非 ACP 返信パスにルーティングしない

src/acp/runtime/registry.ts に以下の API を実装します。ランタイムのルックアップは読み取り専用で、プロセスローカルで行われます。

export type AcpRuntimeBackend = {
id: string;
runtime: AcpRuntime;
healthy?: () => boolean;
};
export function registerAcpRuntimeBackend(backend: AcpRuntimeBackend): void;
export function unregisterAcpRuntimeBackend(id: string): void;
export function getAcpRuntimeBackend(id?: string): AcpRuntimeBackend | null;
export function requireAcpRuntimeBackend(id?: string): AcpRuntimeBackend;

acpx ランタイムプラグインのコントラクト

Section titled “acpx ランタイムプラグインのコントラクト”

最初のプロダクションバックエンドである acpx と OpenClaw は、以下の厳格なコマンドコントラクトで接続されます。

  • バックエンド ID: acpx
  • ランタイムハンドルのエンコーディング: runtimeSessionName = acpx:v1:<base64url(json)>
  • 主要なコマンド例:
    • セッション確保: acpx --format json --json-strict --cwd <cwd> <agent> sessions ensure --name <name>
    • プロンプト実行: acpx --format json --json-strict --cwd <cwd> <agent> prompt --session <name> --file -

ストリーミングイベントの変換ルールは以下の通りです。

  • text => text_delta/output
  • thought => text_delta/thought
  • tool_call => tool_call
  • done => done
  • error => error

src/config/sessions/types.ts の SessionEntry を以下のように拡張します。

type SessionAcpMeta = {
backend: string;
agent: string;
runtimeSessionName: string;
mode: "persistent" | "oneshot";
cwd?: string;
state: "idle" | "running" | "error";
lastActivityAt: number;
lastError?: string;
};

移行はフェーズ A(二重書き込み)からフェーズ D(レガシー読み取りの廃止)までの 4 段階で実施します。

実装中や運用時に発生する可能性のあるエラーとその対策です。

  • ACP_BACKEND_MISSING: ACP ランタイムバックエンドが設定されていません。acpx ランタイムプラグインをインストールして有効にしてください。
  • ACP_BACKEND_UNAVAILABLE: バックエンドが一時的に利用不可能です。しばらく待ってから再試行してください。
  • ACP_SESSION_INIT_FAILED: ACP セッションランタイムの初期化に失敗しました。
  • ACP_TURN_FAILED: 完了前に ACP のターンが失敗しました。

これらのエラーが発生した際、ACP ルーティングが明示的に選択されている場合は、通常の LLM パスにサイレントフォールバックしてはいけません。

システムの健全性を維持するために、以下のメトリクスを収集してください。

  • バックエンドおよびエラーコード別の ACP spawn 成功/失敗数
  • ACP 実行レイテンシ(キュー待ち、ランタイム処理、配信投影時間)
  • ACP actor の再起動回数とその理由
  • べき等リプレイのヒット率
  • Discord への配信リトライおよびレート制限カウンター

ログには sessionKey, runId, backend, threadId, idempotencyKey を含め、状態遷移を構造化ログとして記録します。

安全なリリースのために、独立したディスパッチキルスイッチ acp.dispatch.enabled を導入します。最初のリリースではデフォルトを false とし、カナリア検証の後に true へ変更します。これが false の場合、ユーザーにはポリシーにより ACP ディスパッチが無効である旨のメッセージが返されます。

実装に関する疑問や、具体的なセットアップのサポートが必要な場合は、AI Setup Assistant を活用してください。

  • src/acp/runtime/registry.test.ts: レジストリのユニットテスト
  • src/infra/outbound/bound-delivery-router.ts: 配信ルーターの実装
  • src/gateway/server-methods/sessions.ts: セッション管理 API
  • src/auto-reply/reply/commands-acp.ts: ACP コマンドルーティングの詳細

エージェントをデプロイしたものの、セッションの状態管理やコマンドの実行制御が複雑すぎて、どこで何が起きているのか分からなくなったことはありませんか?ステートの不整合や、予期せぬ二重投稿に悩まされるのは、開発者にとって共通の痛みです。

今回は、これらの課題を解決するために設計されたACP(Agent Control Plane)の新しいコマンド体系と、その実装ロードマップについて共有します。

  • ACP対応のランタイム環境
  • SQLite(永続化レイヤー用)
  • Discord(フェーズ4以降のチャンネル連携用)

5分で把握できる、新しいACPコマンドの最小パスです。以下のコマンドを使用して、エージェントのライフサイクルを直接制御できます。

Terminal window
# エージェントを起動(spawn)する
/acp spawn <agent-id> [--mode persistent|oneshot] [--thread auto|here|off]
# 実行中の処理をキャンセルする
/acp cancel [session]
# エージェントに指示(steer)を送る
/acp steer <instruction>
# セッションを終了する
/acp close [session]
# アクティブなセッション一覧を表示する
/acp sessions

また、既存のコマンドとの互換性も維持されています。

  • /focus <sessionKey>:引き続きACPターゲットをサポートします。
  • /unfocus:現在のセマンティクスを維持します。
  • /session idle および /session max-age:従来のTTLオーバーライドを置き換えます。

確実な導入のために、以下の7つのフェーズに分けて展開します。

  • ACP制御プレーンの所有権とアダプター境界に関するADRを発行します。
  • DBスキーマを確定させます(acp_sessions, acp_runs, acp_bindings, acp_events, acp_delivery_checkpoint, acp_idempotency)。
  • 安定したACPエラーコード、イベントコントラクト、状態遷移ガードを定義します。

Phase 1: Coreにおける制御プレーンの基盤構築

Section titled “Phase 1: Coreにおける制御プレーンの基盤構築”
  • AcpSessionManager とセッションごとの Actor ランタイムを実装します。
  • ACP用の SQLite ストアとトランザクションヘルパーを実装します。
  • べき等性(idempotency)ストアとリプレイヘルパーを実装します。
  • イベント追加および配信チェックポイントモジュールを実装し、spawn/cancel/close API をトランザクション保証付きでマネージャーに接続します。

Phase 2: Coreルーティングとライフサイクルの統合

Section titled “Phase 2: Coreルーティングとライフサイクルの統合”
  • スレッドに紐づいたACPターンを、ディスパッチパイプラインからACPマネージャーへルーティングします。
  • ACPバインディングやセッションの不変条件が満たされない場合、Fail-closed(失敗時に安全に閉じる)ルーティングを強制します。
  • reset/delete/archive/unfocus のライフサイクルを、ACPの close/unbind トランザクションと統合します。

Phase 3: acpx バックエンドアダプター/プラグイン

Section titled “Phase 3: acpx バックエンドアダプター/プラグイン”
  • ランタイムコントラクト(ensureSession, submit, stream, cancel, close)に基づいた acpx アダプターを実装します。
  • バックエンドのヘルスチェックと起動/停止時の登録処理を追加します。
  • acpx の ndjson イベントを ACP ランタイムイベントに正規化します。
  • バックエンドのタイムアウト、プロセス監視、再起動/バックオフポリシーを適用します。

Phase 4: 配信プロジェクションとチャンネルUX(Discord優先)

Section titled “Phase 4: 配信プロジェクションとチャンネルUX(Discord優先)”
  • チェックポイントからの再開が可能なイベント駆動型チャンネルプロジェクションを実装します。
  • ストリーミングチャンクをまとめ、レート制限を考慮したフラッシュポリシーを適用します。
  • 1回の実行につき、最終的な完了メッセージが「正確に一度(exactly-once)」配信されることを保証します。
  • SessionEntry.acp プロジェクションへの二重書き込みと、ACP SQLite を Source-of-Truth(信頼できる唯一の情報源)とする構成を導入します。
  • レガシーなACPメタデータ行のための移行ユーティリティを追加します。
  • 読み取りパスを ACP SQLite プライマリに切り替え、古いルーティングを削除します。

Phase 6: ハーデニング、SLO、およびスケール制限

Section titled “Phase 6: ハーデニング、SLO、およびスケール制限”
  • コンカレンシー制限(グローバル/アカウント/セッション)、キューポリシー、タイムアウト予算を強制します。
  • テレメトリ、ダッシュボード、アラートしきい値を整備します。
  • クラッシュリカバリと重複配信抑制のカオステストを実施します。

  • Core制御プレーンモジュールとテスト
  • DBマイグレーションとロールバックプラン
  • ディスパッチおよびコマンド間でのACPマネージャーAPI統合
  • プラグインランタイムブリッジにおけるアダプター登録インターフェース
  • acpx アダプターの実装とテスト
  • ライフサイクルフック(reset/delete/archive/unfocus)
  • 設定のバリデーションと優先順位テスト
  • 運用ドキュメントとトラブルシューティング用ランブック
  • Unit tests: DBトランザクション境界、状態遷移ガード、べき等性セマンティクス、Actorのシリアル化、acpx イベントパーサーなど。
  • Integration tests: フェイクアダプターを用いたストリーミング動作、チェックポイントからの再開、プラグインサービスの登録と解除など。
  • Gateway e2e tests: スレッドを用いたマルチターンな対話、Gateway再起動後のセッション継続、重複コマンドのリトライ耐性など。

運用中に想定される問題と、その対策をまとめました。

  • 移行中の重複配信
    • 対策:単一の送信先リゾルバーと、べき等なイベントチェックポイントを使用します。
  • 高負荷時のプロセスバタつき
    • 対策:セッションごとの長寿命なオーナー、コンカレンシー制限、バックオフ制御を導入します。
  • プラグインの欠落または設定ミス
    • 対策:オペレーター向けに明示的なエラーを表示し、Fail-closedなルーティングを強制します(通常のセッションパスへの暗黙的なフォールバックは行いません)。
  • 制御プレーンストアの破損
    • 対策:WALモードの利用、バックアップ/リストアフック、読み取り専用フォールバック診断を用意します。

現在の実装を保守しやすくするため、以下のリファクタリングを完了しています。

  1. ACPディスパッチポリシーの集約: src/acp/policy.ts を通じて、共有ポリシーロジックを消費するように変更しました。
  2. コマンドハンドラーの分割: commands-acp.ts を薄いルーターにし、ライフサイクル、ランタイムオプション、診断などのドメインごとに分割しました。
  3. セッションマネージャーの責務分割: manager.core.ts, manager.types.ts, manager.utils.ts に分割し、見通しを良くしました。
  4. acpx ランタイムアダプターのクリーンアップ(任意): プロセス実行、イベントパース、APIサーフェスの分離を推奨しています。

さらなる詳細は AI Setup Assistant で確認できます。

OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。