Discord非同期インバウンドワーカー計画

目的

Discordリスナータイムアウトをユーザーが遭遇する障害モードから排除する。インバウンドDiscordターンを非同期にする:

  1. Gatewayリスナーがインバウンドイベントを素早く受け入れて正規化。
  2. Discord実行キューが、現在と同じ順序境界をキーとしたシリアライズ済みジョブを格納。
  3. ワーカーがCarbonリスナーのライフタイム外で実際のエージェントターンを実行。
  4. 実行完了後、元のチャンネルまたはスレッドに返信を配信。

エージェント実行自体は進行中なのに、channels.discord.eventQueue.listenerTimeoutでキューに入ったDiscord実行がタイムアウトする問題の長期的な修正。

現在の状態

この計画は部分的に実装済み。

完了済み:

  • Discordリスナータイムアウトとdiscord実行タイムアウトが別の設定に。
  • 受け入れたインバウンドDiscordターンがsrc/discord/monitor/inbound-worker.tsにエンキュー。
  • ワーカーがCarbonリスナーの代わりに長時間実行ターンを所有。
  • 既存のルートごとの順序がキューキーで保持。
  • Discordワーカーパスのタイムアウトリグレッションカバレッジが存在。

未完了:

  • DiscordInboundJobはまだ部分的にしか正規化されておらず、ライブランタイム参照を保持
  • コマンドセマンティクス(stopnewreset、将来のセッションコントロール)がまだ完全にワーカーネイティブではない
  • ワーカーの可観測性とオペレーターステータスがまだ最小限
  • 再起動耐久性がまだない

ターゲットアーキテクチャ

1. リスナーステージ

DiscordMessageListenerがイングレスポイントのまま、その役割は:

  • プリフライトとポリシーチェックの実行
  • 受け入れた入力をシリアライズ可能なDiscordInboundJobに正規化
  • セッションごとまたはチャンネルごとの非同期キューにジョブをエンキュー
  • エンキュー成功後すぐにCarbonに戻る

2. 正規化されたジョブペイロード

ターンを後で実行するために必要なデータのみを含むシリアライズ可能なジョブ記述子を導入。ジョブペイロードにはライブCarbonオブジェクトや可変クロージャを含めてはならない。

3. ワーカーステージ

Discord固有のワーカーランナーを追加。ターンコンテキストの再構築、メディア読み込み、エージェントターンのディスパッチ、最終返信ペイロードの配信、ステータスと診断の更新を担当。

4. 順序モデル

順序は特定のルート境界に対して現在と同等でなければならない。異なるDiscordチャンネルは引き続き独立して進行可能。

5. タイムアウトモデル

カットオーバー後、2つの別々のタイムアウトクラス:

  • リスナータイムアウト: 正規化とエンキューのみをカバー。短くあるべき。
  • 実行タイムアウト: オプション、ワーカー所有、明示的、ユーザーに可視。

受入基準

  1. Discordリスナータイムアウトが正常な長時間実行ターンを中断しない。
  2. リスナーのライフタイムとエージェントターンのライフタイムがコード上で別の概念。
  3. 既存のセッションごとの順序が保持。
  4. ACPバウンドDiscordチャンネルが同じワーカーパスを通じて動作。
  5. stopが旧リスナー所有のコールスタックではなくワーカー所有の実行をターゲット。
  6. タイムアウトと配信失敗が明示的なワーカーアウトカムとなり、サイレントなリスナードロップではない。