Skip to content

fix(antigravity): stream chat history to disk to avoid OOM - #396

Merged
yuga-hashimoto merged 1 commit into
mainfrom
fix/issue-392-oom
Oct 21, 2026
Merged

yuga-hashimoto merged 1 commit into
mainfrom
fix/issue-392-oom

Conversation

@yuga-hashimoto

Copy link
Copy Markdown
Owner

Summary

Fixes #392

Pre-PR review

判定: APPROVE

ブロッカー

なし

提案(非ブロッキング)

  • app/src/main/java/com/yugahashimoto/andcode/runtime/local/AntigravityMessageStore.kt:82 — messages.mapValues { it.value.toList() } は flush のたびに全セッションのリストをコピーします(flush はストリーミング中の assistant メッセージごとに走る)。encodeToStream は flush の @Synchronized 下で読むので、フィールドを Map<String, List<OpenCodeMessage>> として持つ(追加時だけ MutableList にキャストする)形にすればコピーを省けます。ただし静的型を LinkedHashMap/MutableList にするとシリアライザが解決できないので、Map/List 型を保つ必要があります。今回の OOM 局面でちょうど効く最適化です。
  • app/src/test/java/.../AntigravityMessageStoreTest.kt — 「読み込み失敗時の退避」は検証されていますが、(1) 退避後に2回目の flush でバックアップが増えず置き換わること、(2) 書き込み失敗時に元ファイルが切り詰められず dirty が維持されること(例: 一時ファイルパスをディレクトリにして rename を失敗させる)は未テストです。このPRの中心的な安全保証なので、1本あると退行を防げます。
  • app/src/main/java/.../AntigravityRuntime.kt:58 — 履歴のデコードは従来どおり AntigravityRuntime のコンストラクタ(AndCodeApplication.onCreate のメインスレッド)で同期的に走ります。ストリーム化で中間 String は消えましたが、起動時に全履歴デコードのピークは残るため、将来さらに詰めるなら初回アクセス時ロードも選択肢になります(本PRの回帰ではありません)。

チェック済み項目

  • git fetch origin main 後、git diff origin/main...HEAD の6ファイル全ハンクを確認(store 新規、runtime/target の置換、CrashLog、DiagnosticsSheet、テスト)。
  • i18n: values*/strings.xml に変更なし。新規のユーザー可視文字列・リソースキーは追加されておらず i18n-check への影響なし。CrashLog の追加行は既存の診断レポート(英語・コピー用)と同じ扱いであることを確認。
  • CrashLog: app/build.gradle.kts で buildConfig = true(232行)と versionCode = 66 / versionName = "1.2.27"(136–137行)を確認。BuildConfig.VERSION_NAME/VERSION_CODE は全フレーバーで生成されます。
  • DiagnosticsSheet: ヘッダは title/Time/Version/Thread/Android/Device/Heap/空行の8行で、14 - 8 = 6 行のスタックは従来の 12 - 6 = 6 と同じ。コメントの記述と一致。
  • AntigravityMessageStore: ClaudeMessageStore と同じ decodeFromStream/encodeToStream + temp→rename 方式、@Synchronized による list/append/remove/flush の排他、!loaded 時の .unreadable 退避(失敗時は書かずに dirty 維持)をコードで確認。!file.exists() を読み込み失敗扱いにしない分岐も妥当。
  • AntigravityRuntime: 旧 messages マップへの参照が残っていないこと、persist() 呼び出しが persistRecords()/persistMessages() に全置換されていること(send 内2箇所、archive/create/setSessionModel/setSessionTitle/setSessionMode、remove は両方)を確認。load() は records のみ読み、messages 読み込みは store の init に一本化。
  • AntigravityTarget: kotlinx.coroutines.Dispatchers は既存 import(7行目)。listMessages の withContext(IO) 化と return@withContext の null 分岐が正しいこと、AntigravityRuntime.listMessages の呼び出し元がこの target のみ(rg で確認)であることを確認。deleteSession/createSession/archiveSession も IO ディスパッチ済み。
  • テスト: app/build.gradle.kts の testOptions.unitTests.isReturnDefaultValues = true(204–209行)により、破損履歴テストで呼ばれる android.util.Log.w が unit test で例外にならないことを確認。新テスト3本が temp ファイル非残留・再読込・セッション削除・破損退避を検証。既存の Antigravity 系テスト(Archive/Title/PermissionMode/DiffCapable)が空ディレクトリで runtime を構築する経路も確認。
  • 静的解析: 変更行の最大長は 115 文字(wc -L)、detekt MaxLineLength: 140 内。TooManyFunctions は本変更前から同水準の構成で、新規違反の増加は軽微。@OptIn(ExperimentalSerializationApi::class) も付与済み。
  • リソース/並行性: flush は IO ディスパッチされた send/remove/listMessages からのみ呼ばれ、list も同じモニタで保護。temp ファイルは成功時 rename、失敗時は元ファイルを保持。
  • worktree: .worktree/fix/issue-392-oom が origin/main から1コミット(02a53f61)で、メインの作業ツリーに今回の変更がないことを確認。
  • 注: この環境では bash が制限されているため ./gradlew detekt spotlessCheck / 単体テストの実行はできず、上記はコードとビルド設定の読み合わせによる確認です。CI 実行結果の確認をお願いします。

AntigravityRuntime loaded antigravity-messages.json with readText() and
serialized the whole map with encodeToString() on every message. That held
the entire file as a String on top of the decoded history, the same
duplication fixed for Claude in #350, and could exhaust the heap on a long
chat (#392).

Move the history into AntigravityMessageStore, which reads and writes as a
stream through a temporary file, and keep record writes separate so a
rename or archive no longer rewrites every message.

Crash reports now include the app version and heap usage; the report from
#392 carried neither, so the build it came from could not be identified.
@yuga-hashimoto
yuga-hashimoto merged commit 70c9702 into main Oct 21, 2026
4 checks passed
@yuga-hashimoto
yuga-hashimoto deleted the fix/issue-392-oom branch October 21, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

نهار التطبيق بشكل مفاجئ واعطاني رساله الخطا هذا اتوقع انه مساحه كانت غير كافيه

1 participant