Skip to content

Latest commit

 

History

History
72 lines (51 loc) · 5.09 KB

File metadata and controls

72 lines (51 loc) · 5.09 KB

Design: token-meter TUI plugin untuk opencode

Tanggal: 2026-08-14 Status: Selesai — diimplementasikan dan diverifikasi manual (incl. indikator tambahan cache hit % dan tok/s)

Tujuan

Plugin TUI opencode yang menampilkan bar metrik token di bagian bawah layar session, memungkinkan pengguna memantau pemakaian sesi secara langsung — padanan @deepseek-ai/dsh-token-meter untuk opencode.

Keputusan desain

  • Pendekatan A: plugin TUI murni — satu modul .tsx di config global opencode, didaftarkan via tui.json. Tidak ada komponen server; semua data dibaca dari api.state di proses TUI. (Pendekatan B hybrid server+TUI ditolak: agregat sudah tersedia server-side, tidak ada manfaat. Pendekatan C statusline bawaan tidak tersedia di opencode 1.18.18 — diverifikasi string status_line tidak ada di binary.)
  • Bar pasif tanpa interaksi — selalu tampil di layar session, tanpa toggle/keybind (sesuai pilihan user; dapat ditambah nanti).
  • Metrik lengkap — kumulatif sesi + tekanan konteks live (setara dua proyeksi utama dsh-token-meter).
  • Target: config global ~/.config/opencode — aktif di semua proyek.

File

  1. ~/.config/opencode/plugins/token-meter.tsx — modul TUI plugin:
    • /** @jsxImportSource @opentui/solid */ (entry wajib .tsx agar host Solid transform bekerja)
    • default export { id: "token-meter", tui } — file plugin wajib mengekspor id non-kosong
    • tui(api, options, meta) mendaftarkan slot app_bottom
  2. ~/.config/opencode/tui.json — dibuat baru (belum ada), $schema: https://opencode.ai/tui.json, plugin: ["./plugins/token-meter.tsx"]. TUI plugin tidak punya auto-discovery; wajib didaftarkan.

Data flow

Bar membaca tiga sumber saat refresh:

  • Kumulatif sesiapi.state.session.get(sessionID)tokens.{input, output, reasoning, cache.{read, write}} + cost. Ini agregat DB penuh (kolom session di projector), tidak terpotong limit 100 pesan pada session.messages() (bug #31513).
  • Tekanan konteks live — pesan assistant terakhir yang memiliki tokens (iterasi messages() mundur dari ekor): used = tokens.total ?? input + output + cache.read + cache.write. Mencerminkan konteks request terakhir; turun setelah /compact. Sengaja tidak memakai session.tokens kumulatif untuk tekanan konteks (menghindari bug #30649: cache.read kumulatif menggelembung tanpa batas).
  • Context limitsession.model → lookup api.state.provider[].models[id].limit.context.

Reaktivitas:

  • Subskripsi api.event.on("message.updated") (memicu live update saat streaming), session.updated, session.created, dan event TUI ganti session — nama event persis diverifikasi dari tipe Event["type"] saat implementasi.
  • Interval fallback 2 detik untuk kondisi yang tidak tertutup event; dibersihkan via api.lifecycle.onDispose.
  • api.route.current dibaca ulang setiap refresh; route home → tidak render apa pun.

Rendering

Satu baris di slot app_bottom, warna dari api.theme.current:

in 12.3k │ out 4.5k │ rsn 1.2k │ cR 89.1k cW 2.1k │ hit 68% │ $0.04 │ ctx ██████░░░░ 43% · 128k │ 23.4 tok/s
  • Bucket input/output/reasoning/cache: teks muted
  • Cache hit (DeepSeek definition cache.read / (cache.read + input) kumulatif sesi): teks muted; disembunyikan sampai ada token prompt
  • Cost: warna accent
  • Segmen ctx: progress bar 10 blok + persen + limit model; warna bertingkat dari tema — success (<50%), warning (50–80%), error (>80%)
  • tok/s: kecepatan generasi live — heuristik 4 karakter/token (padanan dsh-token-meter) dari bagian text+reasoning pesan assistant terakhir yang belum time.completed, dihitung terhadap durasi streaming (warm-up 0.5s); hanya tampil saat session.status busy; warna accent
  • Formatter angka kompak (k/M); segmen yang datanya belum tersedia disembunyikan, bar tetap tampil untuk yang lain

Error handling & edge case

  • Route home / belum ada session aktif → render kosong
  • session.get() transien undefined → render kosong sampai definisi
  • Model tidak ditemukan di daftar provider (custom/terhapus) → segmen ctx & limit disembunyikan
  • Belum ada pesan assistant → segmen ctx disembunyikan
  • Belum ada token prompt (input+cache.read = 0) → segmen hit disembunyikan
  • Status tidak busy atau pesan assistant terakhir sudah time.completed → segmen tok/s disembunyikan; awal streaming (<0.5s) atau belum ada bagian teks juga disembunyikan (anti-noise)
  • Semua angka di-guard NaN/negatif sebelum format
  • Gagal load plugin → runtime opencode me-rollback registrasi otomatis

Verifikasi

  • Typecheck tsc --noEmit di ~/.config/opencode terhadap @opencode-ai/plugin/tui (1.18.18 sudah terpasang di config dir)
  • Uji manual setelah restart opencode: streaming live, ganti session (/new, /sessions), home screen kosong, /compact menurunkan persen ctx, session kosong tidak menampilkan segmen ctx

Catatan

  • Config dir bukan git repo → dokumen ini tidak di-commit; plugin dan spec sama-sama berada di ~/.config/opencode.
  • API slot TUI berlabel eksperimental; risiko break saat upgrade major opencode diterima (preseden: opencode-drawer-statusline).