Skip to content

refresh usage after turn_ja

Kazushi Kamegawa edited this page Aug 12, 2026 · 1 revision

会話ターン終了後の Codex 残量更新

English

日付: 2026-08-12 追跡: Issue #143;サブIssue #144、#145、#146、#147 実装: codex/feature-refresh-usage-after-turn、PR #142

背景

Remaining Usage Flyout(ADR-005)は、残量表示の鮮度を接続世代(connection generation)と60秒TTLの範囲に限定した。サインイン後最初のReady状態で1回だけ取得し、ポップアップを開く操作はTTL経過後のみ再取得し、Busy→Readyのターン遷移単体では再取得しない、という設計である。これは通常のターンでは表示を安定させたが、同時に、モデル呼び出しを消費し終えたばかりのターンでも、最大1分間は古い残量パーセンテージが表示され続けることを意味した。本計画は、既存モデルの保証を一切変更せずに、その上に明示的な「残量消費確定点」を追加する。

設計

  • 会話ターンの完了、およびコンテキスト圧縮の完了を、ADR-005がすでに除外しているBusy→Ready状態遷移とは独立した、明示的な残量消費確定点として扱う。
  • 該当イベントの既存UI transcript/status投影が完了した後、worker/account/rateLimits の読み取りを1回強制する。「強制」とは、60秒TTLチェックを回避することを意味するが、既存の接続世代・pushバージョンによるガードは引き続き通過する必要があり、これにより同時発生するpushやライフサイクル無効化が、古い実行中の読み取りより優先される。
  • TurnCompleted は、app-serverが中断されたと報告するターンも対象に含む——それらも turn/completed として届く。トランスポートレベルの障害(ネットワーク切断、app-serverのプロセス終了)は別で、代わりに Degraded 接続状態として現れる。この状態ではすでに残量は利用不可と扱われるため、明示的に強制再取得のトリガーとはしない。最後に成功したスナップショットは、再接続によって利用可能状態が回復するまでそのまま表示され続ける。
  • コンテキスト圧縮には独自のトリガーが必要だった。/compact はモデル呼び出しを消費するが、app-serverは圧縮完了後に必ずしも turn/completed を送るとは限らないためである。Workerはすでに同じギャップに対処するため、圧縮完了後に Ready 接続状態へ復帰させる特別処理を行っている。
  • 強制読み取り自体が失敗した場合、最後に成功したスナップショットとそのタイムスタンプは表示され続け、次のターン/圧縮の確定点(または既存のTTL・/status 経路)で再試行される。

実装フェーズ

  1. 設計とADR(#144)— ADR-005および設計・実装ドキュメントの残量鮮度セクションを、新しいトリガーとターン失敗時の明示的な除外を含めて改訂する。
  2. 実装とテスト(#145)— ChatViewModel.OnConversationEventAsync(TurnCompleted 時)と ChatViewModel.OnContextCompactedAsync(圧縮完了時)の両方から強制再取得を行い、既存の再取得ゲート・接続世代・pushバージョン・lifetimeキャンセルを再利用する。Worker/RPC契約、XAML、パッケージへの変更はない。
  3. 実機検証(#146)— Visual Studio Experimental Instanceにおいて、通常のターン終了後、/compact 後、ターン中断後のそれぞれで、ヘッダー・Usageポップアップ・更新時刻が同期することを確認する。
  4. 終了失敗系のフォローアップ(#147)— app-serverプロトコルに turn/completed とは別の終了失敗系通知が存在するかを確認し、存在する場合は強制再取得のトリガーをそこまで拡張する。

受け入れ基準と検証

  • TurnCompleted イベントは、TTL内であっても残量読み取りをちょうど1回追加で強制し、ヘッダー・ポップアップには新しいパーセンテージと更新時刻が反映される。
  • 完了した context/compacted イベントについても同様。進行中の圧縮イベントは何もしない。
  • 残量が利用不可(サインアウト、切断、または Degraded)の場合は強制読み取りを行わない。
  • 強制読み取りが失敗した場合、最後に成功したスナップショットが維持され、次の確定点で再試行される。
  • 既存の回帰テストは引き続き成功する: Busy→Ready単体では再取得しないこと、pushは常に古い実行中の読み取りに勝つこと、dispose後のビューモデルは遅延応答を破棄すること。
  • dotnet build CodexForVisualStudio.slnx -c Release は警告ゼロで成功し、Codex.VisualStudio.Core.Tests と Codex.VisualStudio.Ui.Tests の全件が成功する。

非スコープ

Worker/RPC契約のバージョン更新、新規NuGetパッケージ、XAMLの変更は行わない。また、Degraded で終了したターンに対する強制再取得トリガーもここでは追加しない(#147 で未解決の論点として別途追跡し、ここでは前提としない)。

Clone this wiki locally