Files
GMW/docs/specs/2026-08-24-attachment-delay-fix.md
T
asepharyana b3418ad799 feat: Implement video capture improvements and mobile navigation fixes
- Added eager selfbot voice connection establishment to ensure video capture works seamlessly during voice channel joins.
- Introduced a manual video watch command for selfbots to allow operators to initiate screen recording of other members' streams.
- Enhanced video recording functionality to split recordings into segments based on user activity, similar to voice recordings.
- Fixed mobile navigation issues by extending the navbar to include all items and ensuring responsive form controls.
- Standardized error handling across frontend components to improve user experience during failures.
2026-09-11 18:56:28 +07:00

3.3 KiB
Raw Blame History

Spec: Perbaiki Delay Attachment 162s→<20s (GMW AI Analysis)

Tanggal: 2026-08-24 · Repo ~/GMW · Service discord-gateway

Evidence (audit produksi)

Klaster pesan attachment delay ~330–400 detik. Trace pesan 1541417073245290638 (.gif): 19:01:08 dibuat → 19:01:09 batch incomplete → fan-out individual → guard upload-pending mengembalikan results:[] → diperalakukan sukses (complete ... (undefined)) → row tertahan ai_status='processing' tanpa penanggung jawab → 19:06:12 cleanup mengembalikan ke pending (tepat 300s) → baru dianalisis. Plus vision gagal 3× utk GIF besar ("Stream ended before producing a non-ping SSE event") → degradasi teks.

Root causes

  • A (fatal): individualFallbackProcessor.processIndividualFallback memperlakukan ok:true + results:[] sebagai sukses. Race-guard upload di ai-analysis-worker.processIndividual sengaja balik results:[] (desain lama) → pesan yatim processing sampai cleanup 300s.
  • B: llmVision hanya mencoba stream:true; kegagalan SSE truncation pada gambar besar = 3 retry sia-sia (semua jalur sama) → bukti media hilang.
  • C: safety-net cleanup 300s terlalu lambat sbg satu-satunya pemulih processing.

Fix

  1. F1 — sinyal eksplisit upload-pending: IndividualOkResponse + field opsional uploadPending?: boolean. Worker set uploadPending:true saat race guard kena.
  2. F2 — processor menangani 3 kondisi via helper murni baru classifyIndividualWorkerResult(result): "success" | "upload_pending" | "incomplete" | "error" (modul baru fallbackResultClassifier.ts, zero-dep agar mudah dites):
    • upload_pending → tulis ulang row ke pending (pola sama dgn revert apiFailed di batchProcessor) + broadcast + re-schedule analisis percakapan segera (dynamic import batchScheduler, pola anti-siklus yg sudah ada) → retry dalam ~250ms begitu upload beres. Bukan error, tidak naikkan CB counter.
    • incomplete (flags analysis_incomplete) → perilaku lama (exhausted path).
    • error / results kosong tanpa penjelasan → throw transien (retry oleh recovery), BUKAN sukses palsu. Log "(undefined)" hilang.
  3. F3 — vision non-stream fallback: di llmVision, jika error match /Stream ended before producing a non-ping SSE|stream ended/i → coba SEKALI lagi dengan stream:false (router agregasi penuh; timeout tetap 60s). Konversi hard-fail jadi sukses.
  4. F4 — turunkan safety net: default revertStuckProcessingMessages 300000 → 120000 ms.

File disentuh

  • src/modules/ai-moderation/fallbackResultClassifier.ts (BARU, pure)
  • src/modules/ai-moderation/ai-analysis-worker.ts (tipe + set flag uploadPending)
  • src/modules/ai-moderation/individualFallbackProcessor.ts (konsumsi classifier + reschedule)
  • src/modules/ai-moderation/llmClient.ts (fallback non-stream di llmVision)
  • src/modules/message-capture/messagesCleanup.ts (default 120s)

Verifikasi

  • Test baru tests/fallbackResultClassifier.test.ts (4 klasifikasi + edge kosong).
  • Gate: tsc --noEmit, biome error-level, vitest run semua hijau.
  • Deploy GHA sukses; pasca-deploy: pesan attachment baru p50 < 20s (SELECT percentile_cont(0.5) ... WHERE metadata attachments>0 AND created_at > deploy), tidak ada lagi "complete ... (undefined)".