Steven
Steven5 minit bacaan

Cara Menstrim Laporan Langsung Tanpa Kelipan

Apabila mesyuarat anda tamat, ringkasan GeekBye kini terisi secara langsung dan bukannya membuat anda merenung pemutar menunggu. Menjadikan UI penstriman terasa tenang dan bukannya bergegar memerlukan penyelesaian kelipan dua kali — sekali untuk medan berstruktur, sekali untuk markdown — dan pembetulan kedua ialah sebuah renderer yang sudah kami miliki.

Kejuruteraan
Frontend
Streaming
GeekBye Releases
Cara Menstrim Laporan Langsung Tanpa Kelipan

Sebelum keluaran ini, menamatkan mesyuarat GeekBye bermakna menonton pemutar menunggu. Aplikasi akan menghantar keseluruhan transkrip anda untuk dianalisis, menunggu ringkasan penuh — skor, perkara penting, item tindakan, semuanya — kemudian menjatuhkannya ke skrin serentak. Berfungsi, tetapi ia terasa perlahan, kerana anda merenung kekosongan sementara ia bekerja.

GeekBye v1.6.13–v1.6.15 mengubahnya menjadi laporan yang mengalir masuk secara langsung, medan demi medan, sambil ia dijana. Bahagian yang menarik bukanlah penstrimannya — tetapi segala yang perlu kami lakukan supaya penstriman tidak kelihatan bergegar. Penstriman yang tenang dan penstriman yang tersekat-sekat ialah ciri yang sama dengan pelaksanaan yang sangat berbeza.

Kelipan, bahagian satu: jangan biarkan setiap ketulan menggegarkan React

Ringkasan bukanlah satu gumpalan — ia ialah medan berstruktur (skor keseluruhan, perkara penting, item tindakan, dan sebagainya) yang dipancarkan backend satu demi satu melalui server-sent events. Cara naif untuk memaparkannya adalah mengemas kini keadaan React pada setiap peristiwa sebaik ia tiba.

Buat begitu, dan anda akan mendapat kelipan. Setiap medan yang tiba mencetuskan pemaparan semulanya sendiri; komponen yang memaparkan "kosong" akan mount, kemudian unmount, kemudian remount sebagai "dimuatkan"; susun atur bergegar pada setiap paket. Laporan memasang dirinya sendiri di depan anda dengan cara yang paling teruk — jelas kelihatan, gugup.

Pembetulannya ialah disiplin dua bahagian. Pertama, kumpulkan medan yang masuk dalam sebuah ref — bekas boleh ubah yang tidak mencetuskan pemaparan — dan terbitkan ke keadaan React sekali setiap ketulan dengan salinan baharu, supaya pepohon dikemas kini secara sengaja dan bukannya pada setiap mikro-peristiwa. Kedua, paparkan satu pepohon komponen yang stabil sepanjang masa, sama ada sedang distrim mahupun selesai, dengan pemegang tempat sebaris untuk medan yang belum tiba:

// accumulate in a ref, publish once per chunk
partialRef.current = { ...partialRef.current, [field]: value }
setPartial({ ...partialRef.current })

// one tree, never swapped; missing fields show a placeholder in place
const report = isStreaming ? partial : saved
<Score>{report.overallScore ?? '…'}</Score>

Komponen yang memaparkan skor tidak pernah unmount — ia hanya memaparkan sehingga nombornya tiba, kemudian nombornya. Tiada apa-apa bergegar. Dan objek yang dipasang sepenuhnya tetap dicache ke pangkalan data setempat pada akhirnya, supaya UI penstriman dan storan tahan lama wujud bersama tanpa bergaduh.

Kelipan, bahagian dua: renderer yang sudah kami miliki

Kelipan kedua lebih halus dan hidup dalam markdown itu sendiri. Laporan memaparkan markdown kaya — tajuk, tebal, senarai, blok kod. Tetapi markdown yang tiba di tengah strim, pada bila-bila masa, separuh siap. Satu senarai dengan satu butir setakat ini. Satu pagar kod yang telah dibuka tetapi belum ditutup. Satu penanda tebal yang belum ada pasangan.

Sebuah renderer markdown konvensional menghurai semula keseluruhan rentetan pada setiap token, dan keadaan separuh siap itu terhurai menjadi sesuatu yang berbeza setiap kali — jadi senarai berkelip, blok kod berkelip buka-tutup, susun atur melompat sambil token selesai. Ia ialah pemasangan gugup yang sama seperti sebelumnya, satu lapisan lebih dalam.

Pembetulannya hampir memalukan kerana begitu mudah didapati: kami sudah menggunakan renderer markdown yang sedar-penstriman untuk sembang AI langsung. Sebuah renderer yang dibina untuk bertolak ansur dengan token tidak lengkap — untuk memaparkan markdown separuh siap secara stabil dan hanya menetapkannya apabila token selesai — dan bukannya menghurai semula dari kosong setiap kali. Laporan hanya perlu menggunakan yang sama. Kami telah menyelesaikan masalah yang tepat ini untuk sembang berbulan-bulan sebelumnya; "pembetulan" untuk laporan adalah menyedari bahawa kami sudah ada alatnya dan mengarahkannya ke permukaan kedua. Guna semula mengalahkan bina semula.

Bonusnya: salin kaya ialah masalah format papan keratan

Sebaik laporan kelihatan bagus, orang mahu menampalnya — ke dokumen, e-mel — dan mengekalkan formatnya serta tangkapan skrinnya. Naluri adalah menyirikan laporan menjadi rentetan markdown dan berharap destinasi memaparkannya. Biasanya tidak.

Jawapan sebenar ialah papan keratan menyimpan berbilang perwakilan serentak. Jadi kami menulis dua: sebuah versi HTML dengan format utuh dan tangkapan skrin terbenam sebagai imej sebaris, dan sebuah sandaran teks biasa untuk destinasi yang tidak menerima HTML. Tampal ke editor kaya dan anda mendapat laporan berformat dengan gambar; tampal ke kotak teks biasa dan anda mendapat teks bersih. "Salin kaya" tidak pernah menjadi masalah penyirian — ia ialah masalah pilih-format-papan-keratan-yang-betul.

Keluaran yang sama juga memberikan laporan label gaya-sembang Me / Them dengan kedua-dua penutur dijajarkan ke sisi bertentangan, supaya sebuah transkrip terbaca seperti perbualan yang sebenarnya, dan memindahkan tangkapan skrin anda sendiri ke sisinya sendiri agar sepadan. (Satu keluaran dalam tetingkap ini, v1.6.14, ialah pembinaan semula tulen — tiada cerita di situ, dan jujur untuk mengatakannya.)

Tiga perkara yang diajar UI penstriman kepada kami

  1. Timbunkan medan yang distrim, terbitkan sekali setiap ketulan. Membiarkan setiap server-sent event memacu kemas kini keadaannya sendiri ialah puncak kelipan. Sebuah pengumpul ref serta satu penerbitan setiap ketulan, ke dalam pepohon yang tidak pernah unmount, mengubah pemasangan gugup menjadi pengisian yang tenang.
  2. Apa-apa sahaja yang distrim memerlukan renderer yang sedar-penstriman. Renderer yang menghurai semula keseluruhan rentetan setiap token akan berkelip pada markdown separuh siap. Gunakan yang dibina untuk input tidak lengkap — dan jika anda sudah ada satu untuk permukaan lain, guna semula sebelum membina yang kedua.
  3. Salin kaya adalah tentang format papan keratan, bukan penyirian. Tulis text/html dengan imej terbenam dan sandaran text/plain. Papan keratan direka untuk membawa kedua-duanya; gunakannya.

Ini ialah bab kelima daripada kisah kebolehpercayaan-dan-penggilapan yang menjadi GeekBye v2. Untuk bab sebelumnya, lihat pepijat fon telinga (v1.6.12); untuk tempat di mana idea server-sent events yang sama kemudiannya menjadi keseluruhan pengangkutan sandaran, transkripsi langsung apabila tembok api menyekat WebSockets (v2.0.8); dan untuk keseluruhan lengkoknya, anatomi menghantar perisian hingga ke kesempurnaan.

Artikel Berkaitan

Sambungan yang Terputus Tidak Sepatutnya Merosakkan Seluruh Aplikasi Anda — Tetapi Aplikasi Kami Ya
Steven
Steven6 minit bacaan

Sambungan yang Terputus Tidak Sepatutnya Merosakkan Seluruh Aplikasi Anda — Tetapi Aplikasi Kami Ya

Apabila backend kami luar talian di tengah-tengah mesyuarat, ia bukan sekadar menjeda transkripsi — ia merosakkan seluruh aplikasi. Puncanya ialah satu peristiwa yang tidak dikendalikan, dan pembaikannya hanya sepuluh baris. Inilah kelompok keluaran yang membuatkan GeekBye kekal log masuk dan kekal bersambung menerusi perkara-perkara yang dahulunya membunuhnya.

Kejuruteraan
Kebolehpercayaan
Electron
Aplikasi Mac Anda Memberi Akses Mikrofon — Kemudian Melupakannya Setiap Kali Dibuka
Steven
Steven5 minit bacaan

Aplikasi Mac Anda Memberi Akses Mikrofon — Kemudian Melupakannya Setiap Kali Dibuka

GeekBye meminta kebenaran mikrofon, anda memberikannya, dan ia berfungsi. Pada pembukaan seterusnya: hilang. Dan aplikasi itu langsung tidak muncul dalam Tetapan Sistem → Mikrofon. Punca sebenarnya ialah ciri keselamatan macOS yang secara senyap menjalankan aplikasi dari satu laluan yang lenyap — inilah diagnosisnya dan penyelesaian satu-gesaan.

macOS
Kebenaran
Kejuruteraan
Kami Memadam 5,000 Baris Kod Audio — dan Transkrip Mula Muncul Dua Kali
Steven
Steven6 minit bacaan

Kami Memadam 5,000 Baris Kod Audio — dan Transkrip Mula Muncul Dua Kali

GeekBye v1.6 mencabut dua transkriber Swift atas peranti dan menggantikannya dengan satu saluran paip bersatu — pemadaman bersih lebih 5,000 baris, dilakukan sewaktu orang berada di tengah-tengah mesyuarat dalam apl. Kemudian transkrip mula muncul dua kali, kerana pepijat itu berpindah ke satu lapisan yang masih menyangka ada dua enjin.

Kejuruteraan
Transkripsi
Seni Bina