目的
main, subagent, および acp のすべてのランタイムにおいて、バッファリング(結合)、チャンク化、配信順序の制御、およびクラッシュリカバリの挙動を統一するため、単一の共有ストリーミングパイプラインを構築します。
背景
- 現在の挙動は、ランタイムごとの複数の処理パスに分かれて実装されています。
- フォーマットや結合に関するバグ修正が、特定のパスにのみ適用され、他に取り残されるケースが発生しています。
- 配信の一貫性、重複の抑制、およびリカバリ(復旧)セマンティクスの管理が複雑になっています。
目指すべきアーキテクチャ
単一のパイプラインに対し、ランタイム固有のアダプターを接続する構造にします:- ランタイムアダプター: 正規化されたイベントのみを発行する。
- 共有ストリームアセンブラ: テキスト、ツール、ステータスの各イベントを結合し、確定させる。
- 共有チャネルプロジェクター: チャネル固有のチャンク化とフォーマットを一度だけ適用する。
- 共有配信元帳 (Ledger): べき等な送信とリプレイのセマンティクスを強制する。
- アウトバウンドチャネルアダプター: 実際の送信を実行し、配信チェックポイントを記録する。
turn_started(ターン開始)text_delta(テキスト差分)block_final(ブロック確定)tool_started(ツール開始)tool_finished(ツール終了)status(ステータス)turn_completed(ターン完了)turn_failed(ターン失敗)turn_cancelled(キャンセル)
ワークストリーム
1) 正規ストリーミングコントラクト (契約)
- 厳格なイベントスキーマと検証ロジックをコア側に定義。
- アダプターのコントラクトテストを追加し、各ランタイムが互換性のあるイベントを発行することを保証。
- 不正な形式のランタイムイベントを早期に拒否し、構造化された診断情報を表示。
2) 共有ストリームプロセッサ
- ランタイムごとにバラバラだった結合・投影ロジックを、単一のプロセッサに統合。
- プロセッサがテキスト差分のバッファリング、アイドル時のフラッシュ、最大チャンクサイズでの分割、および完了時のフラッシュを管理。
- ACP/main/subagent 間での設定の乖離を防ぐため、ストリーミング構成の解決を単一のヘルパーに移動。
3) 共有チャネル投影
- チャネルアダプターを「受動的」なものに保つ: 確定したブロックを受け取って送信するだけの役割にする。
- Discord 固有のチャンク化の癖などを、チャネルプロジェクター内に集約。
- 投影ステップの前までは、パイプラインを特定のチャネルに依存しない(チャネルアグノスティックな)状態に保つ。
4) 配信元帳 + リプレイ
- ターンごと、チャンクごとの配信 ID を導入。
- 物理的な送信の前後でチェックポイントを記録。
- 再起動時、未完了のチャンクをべき等にリプレイし、重複送信を避ける。
5) 移行と切り替え
- フェーズ 1 (Shadow mode): 新しいパイプラインで出力を計算しつつ、送信自体は旧パスで行い、結果を比較検証する。
- フェーズ 2 (Cutover): リスクを考慮しながら、ランタイムごとに順次新パイプラインへ切り替える (
acp->subagent->mainまたはその逆)。 - フェーズ 3: ランタイム固有の古いストリーミングコードを削除。
非目標
- 本リファクタリングにおいて、ACP のポリシーや権限モデルの変更は行わない。
- 投影の互換性修正を除き、チャネル固有の機能拡張は行わない。
- 通信路(トランスポート)やバックエンドの再設計は行わない(イベントの互換性に必要な場合を除き、acpx プラグインコントラクトは現状を維持)。
リスクと緩和策
- リスク: 既存の main/subagent パスでのデグレード(先祖返り)。
- 緩和策: シャドウモードでの比較、アダプターのコントラクトテスト、チャネルの E2E テストの実施。
- リスク: クラッシュリカバリ時の重複送信。
- 緩和策: 永続的な配信 ID の導入と、配信アダプターでのべき等なリプレイの実装。
- リスク: 各ランタイムアダプターが再び独自の進化を遂げてしまう。
- 緩和策: すべてのアダプターに対し、共有コントラクトテストスイートへの合格を必須とする。
合格基準
- すべてのランタイムが共有ストリーミングコントラクトテストに合格すること。
- Discord において、ACP/main/subagent が微小な差分(delta)に対しても同等の改行・チャンク化挙動を示すこと。
- クラッシュ/再起動後のリプレイにおいて、同一の配信 ID に対して重複したチャンクが送信されないこと。
- レガシーな ACP プロジェクター/アセンブラパスが削除されていること。
- ストリーミング設定の解決処理が共通化され、ランタイムに依存しないこと。