統一ランタイムストリーミングリファクタリング計画
目的
main、subagent、acpに共通の1つのストリーミングパイプラインを提供し、すべてのランタイムで同一の結合、チャンク分割、配信順序、クラッシュリカバリ動作を実現する。
なぜ必要か
- 現在の動作はランタイム固有の複数のシェイピングパスに分散している。
- フォーマット/結合のバグを1つのパスで修正しても、他では残る可能性がある。
- 配信の一貫性、重複抑制、リカバリセマンティクスの推論が困難。
ターゲットアーキテクチャ
単一パイプライン、ランタイム固有のアダプター:
- ランタイムアダプターは正規イベントのみを発行。
- 共有ストリームアセンブラーがテキスト/ツール/ステータスイベントを結合・最終化。
- 共有チャンネルプロジェクターがチャンネル固有のチャンク分割/フォーマットを1回だけ適用。
- 共有配信台帳が冪等な送信/リプレイセマンティクスを強制。
- アウトバウンドチャンネルアダプターが送信を実行し、配信チェックポイントを記録。
正規イベントコントラクト:
turn_startedtext_deltablock_finaltool_startedtool_finishedstatusturn_completedturn_failedturn_cancelled
ワークストリーム
1) 正規ストリーミングコントラクト
- コアで厳密なイベントスキーマ+バリデーションを定義。
- 各ランタイムが互換イベントを発行することを保証するアダプターコントラクトテストを追加。
- 不正なランタイムイベントを早期に拒否し、構造化された診断を提示。
2) 共有ストリームプロセッサー
- ランタイム固有の結合器/プロジェクターロジックを1つのプロセッサーに置き換え。
- プロセッサーがテキストデルタバッファリング、アイドルフラッシュ、最大チャンク分割、完了フラッシュを所有。
- ACP/main/subagentの設定解決を1つのヘルパーに移動してドリフトを防止。
3) 共有チャンネル投影
- チャンネルアダプターをシンプルに保つ: 最終化されたブロックを受け取って送信。
- Discord固有のチャンク分割の特殊処理をチャンネルプロジェクターのみに移動。
- 投影前のパイプラインをチャンネル非依存に維持。
4) 配信台帳+リプレイ
- ターンごと/チャンクごとの配信IDを追加。
- 物理的な送信の前後でチェックポイントを記録。
- 再起動時に保留チャンクを冪等にリプレイし、重複を回避。
5) 移行とカットオーバー
- フェーズ1: シャドーモード(新パイプラインが出力を計算するが旧パスが送信、比較)。
- フェーズ2: ランタイムごとのカットオーバー(
acp、次にsubagent、次にmain、またはリスク順に逆)。 - フェーズ3: レガシーのランタイム固有ストリーミングコードを削除。
非目標
- このリファクタリングでACPのポリシー/権限モデルは変更しない。
- 投影互換性修正以外のチャンネル固有機能拡張はしない。
- トランスポート/バックエンドの再設計はしない(acpxプラグインコントラクトはイベント同等性に必要でなければそのまま)。
リスクと緩和策
- リスク: 既存のmain/subagentパスでの動作リグレッション。 緩和策: シャドーモードの差分比較+アダプターコントラクトテスト+チャンネルE2Eテスト。
- リスク: クラッシュリカバリ中の重複送信。 緩和策: 永続的な配信ID+配信アダプターでの冪等リプレイ。
- リスク: ランタイムアダプターの再乖離。 緩和策: すべてのアダプターに必須の共有コントラクトテストスイート。
受入基準
- すべてのランタイムが共有ストリーミングコントラクトテストに合格。
- Discord上でACP/main/subagentが微小デルタに対して同等のスペーシング/チャンク分割動作を生成。
- クラッシュ/再起動リプレイが同一配信IDに対して重複チャンクを送信しない。
- レガシーACPプロジェクター/結合器パスが削除されている。
- ストリーミング設定解決が共有され、ランタイム非依存。