gemini-reverse 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG-IDN.md CHANGED
@@ -2,67 +2,67 @@
2
2
 
3
3
  > **Language / Bahasa:** [English](CHANGELOG-EN.md) · [Indonesia](CHANGELOG-IDN.md)  |  **README:** [EN](README.md) · [IDN](README-IDN.md)
4
4
 
5
- Semua perubahan penting pada proyek ini didokumentasikan di file ini.
5
+ Semua perubahan penting pada proyek ini dicatat di sini.
6
6
 
7
7
  ---
8
8
 
9
9
  ## [1.0.7]
10
10
 
11
11
  ### Ditambahkan
12
- - **Extended Thinking** — Parameter `extended_thinking` pada `generateContent`, `generateContentStream`, `sendMessage`, dan `sendMessageStream`. Mengaktifkan mode penalaran yang lebih dalam pada model yang mendukung. Model header dimodifikasi saat request dengan menambahkan flag thinking dan session ID.
13
- - **`StreamingFrameParser`** — Class parser frame stateful incremental yang menggantikan `parseResponseByFrame` yang stateless. Buffer frame parsial secara efisien lintas chunk jaringan tanpa perlu memindai ulang byte yang sudah diproses.
14
- - **Quota & Info Penggunaan** — Property `client.quotas`, `client.usageInfo`, dan `client.abuseStatus` diisi otomatis saat inisialisasi via RPC `CHECK_GEMINI_QUOTA`, `CHECK_QUOTA`, `GET_USAGE_INFO`, dan `GET_ABUSE_STATUS`.
15
- - **Activity Watchdog** — Timer background (`_startActivityWatchdog`) yang mengirim heartbeat berkala setiap 60–300 detik untuk menjaga sesi tetap aktif tanpa perlu request eksplisit dari pengguna.
12
+ - **Extended Thinking** — Parameter `extended_thinking` pada `generateContent`, `generateContentStream`, `sendMessage`, dan `sendMessageStream`. Mengaktifkan mode penalaran mendalam pada model yang mendukung. Model header dimodifikasi saat request dengan menyertakan flag thinking dan session ID.
13
+ - **`StreamingFrameParser`** — Class parser frame stateful yang baru, menggantikan `parseResponseByFrame` yang stateless. Frame parsial di-buffer secara efisien antar chunk jaringan tanpa perlu memindai ulang data yang sudah diproses.
14
+ - **Quota & Info Penggunaan** — Property `client.quotas`, `client.usageInfo`, dan `client.abuseStatus` terisi otomatis saat inisialisasi lewat RPC `CHECK_GEMINI_QUOTA`, `CHECK_QUOTA`, `GET_USAGE_INFO`, dan `GET_ABUSE_STATUS`.
15
+ - **Activity Watchdog** — Timer background yang mengirim heartbeat setiap 60–300 detik secara acak untuk menjaga sesi tetap aktif tanpa perlu request manual.
16
16
  - **`_checkAccountStatus()`** — Method internal untuk memastikan RPC tidak dijalankan pada akun yang dibatasi.
17
- - **`_parseRpcResults()`** — Helper iterator internal untuk mengekstrak body dari respons batch RPC, termasuk penanganan rejection code (code 7 → tandai sebagai unauthenticated).
18
- - **`_sessionid`** — UUID per-sesi yang dibuat di constructor dan diperbarui setiap `init()`. Digunakan sebagai field di model header untuk setiap request generasi.
19
- - **`source_path` di `_batchExecute`** — Parameter opsional (default `/app`, `/usage` untuk `_fetchUsageInfo`).
20
- - **`model_number` di `AvailableModel`** — Field baru yang dicerminkan dari model header ke payload request (`inner[79]`).
21
- - **`buildModelIdNumberMapping()`** — Method static pada `AvailableModel` yang mengembalikan mapping `modelId → modelNumber`.
17
+ - **`_parseRpcResults()`** — Helper internal untuk mengekstrak isi dari respons batch RPC, termasuk penanganan rejection code (kode 7 → tandai sebagai unauthenticated).
18
+ - **`_sessionid`** — UUID per-sesi yang dibuat di constructor dan diperbarui setiap `init()`. Digunakan sebagai field di model header tiap request.
19
+ - **`source_path` di `_batchExecute`** — Parameter opsional (default `/app`, diisi `/usage` untuk `_fetchUsageInfo`).
20
+ - **`model_number` di `AvailableModel`** — Field baru yang diteruskan dari model header ke payload request (`inner[79]`).
21
+ - **`buildModelIdNumberMapping()`** — Method static pada `AvailableModel` yang menghasilkan mapping `modelId → modelNumber`.
22
22
  - **Model baru** — `BASIC_LITE` (`gemini-3-lite`), `PLUS_LITE` (`gemini-3-lite-plus`), `ADVANCED_LITE` (`gemini-3-lite-advanced`).
23
- - **GRPC key baru** — Ditambahkan dari `pr`: `GET_CONVERSATION_TURN`, `UPDATE_CONVERSATION`, `MARK_LAST_CONVERSATION_TURN`, `GENERATE_HEADLINE`, `GET_GEM`, `DELETE_GEM_AND_CONVERSATIONS`, `CREATE_TASK`, `GET_TASK`, `GET_ALL_TASKS`, `GET_TASKS_IN_CONVERSATION`, `GET_CANDIDATES`, `LIST_DISCOVERY_CARDS`, `GET_DISCOVERY_CARD`, `LIST_DISCOVERY_BANNERS`, `LIST_GEMINI_APP_ARTIFACTS`, `DELETE_GEMINI_APP_ARTIFACTS`, `LIST_MEMORIES`, `CREATE_MEMORY`, `UPDATE_MEMORY`, `DELETE_MEMORY`, `DELETE_ALL_MEMORIES`, `CHECK_GEMINI_QUOTA`, `CHECK_QUOTA`, `GET_ABUSE_STATUS`, `UPDATE_USER_PREFERENCES`, `READ_USER_PREFERENCES`, `CONTINUE_SHARED_CONVERSATION`, `GET_USAGE_INFO`.
24
- - **Jitter auto-refresh** — Interval refresh cookie kini menerapkan jitter acak ±15 detik untuk mencegah request background yang tersinkronisasi.
25
- - **`_fetchPreferences()` / `_syncActivity()`** — Menggantikan `_sendBardSettings` / `_sendBardActivity` yang monolitik dengan method khusus yang memisahkan sinkronisasi preferensi dari heartbeat aktivitas.
26
- - **Resolusi model case-insensitive** — `_resolveModelByName` kini mencocokkan nama model dan display name tanpa memperhatikan huruf besar/kecil.
27
- - **Guard akun di `_fetchRecentChats`** — Melewati pengambilan riwayat chat jika status akun tidak tersedia.
23
+ - **GRPC key baru** — `GET_CONVERSATION_TURN`, `UPDATE_CONVERSATION`, `MARK_LAST_CONVERSATION_TURN`, `GENERATE_HEADLINE`, `GET_GEM`, `DELETE_GEM_AND_CONVERSATIONS`, `CREATE_TASK`, `GET_TASK`, `GET_ALL_TASKS`, `GET_TASKS_IN_CONVERSATION`, `GET_CANDIDATES`, `LIST_DISCOVERY_CARDS`, `GET_DISCOVERY_CARD`, `LIST_DISCOVERY_BANNERS`, `LIST_GEMINI_APP_ARTIFACTS`, `DELETE_GEMINI_APP_ARTIFACTS`, `LIST_MEMORIES`, `CREATE_MEMORY`, `UPDATE_MEMORY`, `DELETE_MEMORY`, `DELETE_ALL_MEMORIES`, `CHECK_GEMINI_QUOTA`, `CHECK_QUOTA`, `GET_ABUSE_STATUS`, `UPDATE_USER_PREFERENCES`, `READ_USER_PREFERENCES`, `CONTINUE_SHARED_CONVERSATION`, `GET_USAGE_INFO`.
24
+ - **Jitter pada auto-refresh** — Interval refresh cookie kini ditambahkan jitter acak ±15 detik agar request background tidak tersinkronisasi.
25
+ - **`_fetchPreferences()` / `_syncActivity()`** — Menggantikan `_sendBardSettings` / `_sendBardActivity` dengan method yang lebih khusus, memisahkan sinkronisasi preferensi dari heartbeat aktivitas.
26
+ - **Pencocokan model tidak case-sensitive** — `_resolveModelByName` sekarang mencocokkan nama model dan display name tanpa memperhatikan huruf besar/kecil.
27
+ - **Guard akun di `_fetchRecentChats`** — Pengambilan riwayat chat dilewati kalau status akun tidak tersedia.
28
28
 
29
29
  ### Diubah
30
30
  - **Format model header** — Diperbarui dari `[4]` menjadi `[4,5,6,8]` dengan `model_number` ditambahkan di akhir. Header `x-goog-ext-73010990-jspb` berubah dari `[0]` menjadi `[0,0,0]`.
31
31
  - **`Headers.BATCH_EXEC`** — Diperbarui mengikuti format model header baru.
32
- - **Array request inner** — Ukuran bertambah dari 69 menjadi 81 elemen. `inner[68]` berubah dari `2` menjadi `1`. Slot baru `inner[79]` (model_number) dan `inner[80]` (mode thinking: `2` = extended, `1` = standar).
33
- - **`_initRpc`** — Sekarang memanggil `_fetchPreferences`, `_syncActivity`, `_fetchRecentChats`, `_fetchQuota`, `_fetchExtraQuota`, `_fetchAbuseStatus`, `_fetchUsageInfo` secara berurutan.
32
+ - **Array inner request** — Ukuran bertambah dari 69 menjadi 81 elemen. `inner[68]` berubah dari `2` menjadi `1`. Slot baru: `inner[79]` (model_number) dan `inner[80]` (mode thinking: `2` = extended, `1` = standar).
33
+ - **`_initRpc`** — Kini memanggil `_fetchPreferences`, `_syncActivity`, `_fetchRecentChats`, `_fetchQuota`, `_fetchExtraQuota`, `_fetchAbuseStatus`, `_fetchUsageInfo` secara berurutan.
34
34
  - **Model THINKING dihapus** — `BASIC_THINKING`, `PLUS_THINKING`, `ADVANCED_THINKING` digantikan oleh keluarga model LITE.
35
- - **Cookie upload** — `uploadFile` kini meneruskan cookie sesi bersama header `Push-ID` dan REFERER.
36
- - **Decode HTML entity** — Diperluas untuk mencakup entity numerik (`{`, ``) dan entity bernama tambahan.
37
- - **Header download video** — `_downloadFile` di `video.js` kini mengirim header `Origin` dan `Referer`.
38
- - **Bahasa `fetchGems`** — Menggunakan `this.language` alih-alih hardcode `'en'`.
39
- - **Auto-init saat panggilan pertama** — `generateContent` dan `generateContentStream` memanggil `init()` otomatis jika client belum berjalan.
35
+ - **Cookie pada upload** — `uploadFile` sekarang juga meneruskan cookie sesi bersama header `Push-ID` dan REFERER.
36
+ - **Decode HTML entity** — Diperluas untuk mencakup entity numerik (`{`, ``) dan beberapa entity bernama tambahan.
37
+ - **Header download video** — `_downloadFile` di `video.js` sekarang menyertakan header `Origin` dan `Referer`.
38
+ - **Bahasa di `fetchGems`** — Sekarang menggunakan `this.language` daripada hardcode `'en'`.
39
+ - **Auto-init saat pemanggilan pertama** — `generateContent` dan `generateContentStream` otomatis memanggil `init()` kalau client belum berjalan.
40
40
 
41
41
  ### Diperbaiki
42
- - **Kegagalan upload** — Memperbaiki header `Push-ID`, content-type, dan REFERER yang hilang di `uploadFile`.
43
- - **Format kunci quota** — Entry null pada daftar ID quota kini difilter sebelum digabung, menghasilkan kunci numerik yang bersih (mis. `11`, `4`) alih-alih `-11`, `-4`.
42
+ - **Upload gagal** — Header `Push-ID`, content-type, dan REFERER yang hilang di `uploadFile` sudah diperbaiki.
43
+ - **Format kunci quota** — Entry null pada daftar ID quota sekarang difilter sebelum digabung, menghasilkan kunci numerik yang benar (mis. `11`, `4`) bukan `-11`, `-4`.
44
44
 
45
45
  ---
46
46
 
47
47
  ## [1.0.8]
48
48
 
49
49
  ### Diperbaiki
50
- - Memperbaiki format kunci quota — entry null pada daftar ID quota kini difilter sebelum digabung, menghasilkan kunci numerik yang bersih (mis. `11`, `4`) alih-alih `-11`, `-4`.
50
+ - Format kunci quota — entry null difilter sebelum digabung sehingga menghasilkan kunci numerik yang bersih (mis. `11`, `4`) bukan `-11`, `-4`.
51
51
 
52
52
  ---
53
53
 
54
54
  ## [1.0.6]
55
55
 
56
56
  ### Diperbaiki
57
- - Memperbaiki upload file upload kini mengirim cookie dan header yang diperlukan dengan benar.
58
- - Memperbaiki unduhan media untuk video dan audio yang dihasilkan.
57
+ - Upload file sudah mengirim cookie dan header yang diperlukan dengan benar.
58
+ - Unduhan media untuk video dan audio yang dihasilkan sudah diperbaiki.
59
59
 
60
60
  ---
61
61
 
62
62
  ## [1.0.5]
63
63
 
64
64
  ### Diperbaiki
65
- - Memperbaiki parsing image generation — `GeneratedImage` kini menggunakan pola `client_ref` alih-alih membutuhkan injeksi cookie langsung.
65
+ - Parsing image generation diperbaiki — `GeneratedImage` sekarang pakai pola `client_ref` dan tidak lagi butuh injeksi cookie langsung.
66
66
 
67
67
  ---
68
68
 
package/README-IDN.md CHANGED
@@ -8,18 +8,18 @@ Client Node.js tidak resmi untuk [Google Gemini](https://gemini.google.com), ter
8
8
 
9
9
  ## Fitur
10
10
 
11
- - **Cookie Persisten** — Secara otomatis memperbarui cookie di latar belakang dengan jitter acak untuk mencegah request yang tersinkronisasi. Dioptimalkan untuk layanan yang selalu aktif.
12
- - **Pembuatan Gambar** — Mendukung pembuatan dan pengeditan gambar secara native dengan bahasa natural.
13
- - **Pembuatan Video & Audio** — Mendukung pembuatan video dan konten audio/musik secara native.
14
- - **Deep Research** — Alur kerja penelitian mendalam lengkap dengan pembuatan rencana, polling status, dan pengambilan hasil.
15
- - **Extended Thinking** — Mengaktifkan mode penalaran yang lebih dalam pada model yang mendukung.
16
- - **System Prompt** — Mendukung kustomisasi system prompt model dengan [Gemini Gems](https://gemini.google.com/gems/view).
17
- - **Dukungan Ekstensi** — Mendukung pembuatan konten dengan ekstensi Gemini seperti YouTube dan Gmail.
18
- - **Output Terklasifikasi** — Mengkategorikan teks, pikiran, gambar, video, dan audio dalam respons.
19
- - **Mode Streaming** — Mendukung streaming dengan parser frame stateful incremental, menghasilkan output parsial saat dibuat.
20
- - **Penemuan Model Dinamis** — Menemukan model yang tersedia secara otomatis dari akun Anda saat inisialisasi.
21
- - **Quota & Info Penggunaan** — Mengekspos batas quota akun, penggunaan komputasi, dan status abuse setelah inisialisasi.
22
- - **Activity Watchdog** — Task heartbeat background yang menjaga sesi tetap aktif secara otomatis.
11
+ - **Cookie Persisten** — Cookie diperbarui otomatis di latar belakang dengan jitter acak agar tidak tersinkronisasi. Cocok untuk layanan yang berjalan terus-menerus.
12
+ - **Buat Gambar** — Buat dan edit gambar secara langsung menggunakan bahasa natural.
13
+ - **Buat Video & Audio** — Dukung pembuatan video dan konten audio/musik secara native.
14
+ - **Deep Research** — Alur kerja riset mendalam lengkap: buat rencana, pantau status, dan ambil hasil.
15
+ - **Extended Thinking** — Aktifkan mode penalaran lebih dalam pada model yang mendukung.
16
+ - **System Prompt** — Kustomisasi system prompt model lewat [Gemini Gems](https://gemini.google.com/gems/view).
17
+ - **Dukungan Ekstensi** — Gunakan ekstensi Gemini seperti YouTube dan Gmail dalam percakapan.
18
+ - **Output Terklasifikasi** — Teks, pikiran, gambar, video, dan audio dikelompokkan otomatis dalam respons.
19
+ - **Mode Streaming** — Respons diterima secara bertahap menggunakan parser frame stateful yang efisien.
20
+ - **Penemuan Model Dinamis** — Model yang tersedia untuk akun Anda ditemukan otomatis saat inisialisasi.
21
+ - **Quota & Info Penggunaan** — Batas quota, penggunaan komputasi, dan status abuse akun tersedia setelah inisialisasi.
22
+ - **Activity Watchdog** — Heartbeat berjalan di latar belakang untuk menjaga sesi tetap aktif.
23
23
  - **Dukungan TypeScript** — Deklarasi tipe TypeScript lengkap sudah tersedia.
24
24
 
25
25
  ## Daftar Isi
@@ -30,8 +30,8 @@ Client Node.js tidak resmi untuk [Google Gemini](https://gemini.google.com), ter
30
30
  - [Autentikasi](#autentikasi)
31
31
  - [Penggunaan](#penggunaan)
32
32
  - [Inisialisasi](#inisialisasi)
33
- - [Generate Konten](#generate-konten)
34
- - [Generate Konten dengan File](#generate-konten-dengan-file)
33
+ - [Buat Konten](#buat-konten)
34
+ - [Buat Konten dengan File](#buat-konten-dengan-file)
35
35
  - [Percakapan Multi-Giliran](#percakapan-multi-giliran)
36
36
  - [Lanjutkan Percakapan Sebelumnya](#lanjutkan-percakapan-sebelumnya)
37
37
  - [Baca Riwayat Percakapan](#baca-riwayat-percakapan)
@@ -42,17 +42,17 @@ Client Node.js tidak resmi untuk [Google Gemini](https://gemini.google.com), ter
42
42
  - [Extended Thinking](#extended-thinking)
43
43
  - [Pilih Model Bahasa](#pilih-model-bahasa)
44
44
  - [Daftar Model Tersedia](#daftar-model-tersedia)
45
- - [Terapkan System Prompt dengan Gemini Gems](#terapkan-system-prompt-dengan-gemini-gems)
45
+ - [Pakai System Prompt dengan Gemini Gems](#pakai-system-prompt-dengan-gemini-gems)
46
46
  - [Kelola Custom Gems](#kelola-custom-gems)
47
47
  - [Buat Custom Gem](#buat-custom-gem)
48
- - [Perbarui Gem yang Ada](#perbarui-gem-yang-ada)
48
+ - [Edit Gem yang Ada](#edit-gem-yang-ada)
49
49
  - [Hapus Custom Gem](#hapus-custom-gem)
50
- - [Ambil Proses Berpikir Model](#ambil-proses-berpikir-model)
51
- - [Ambil Gambar dalam Respons](#ambil-gambar-dalam-respons)
52
- - [Generate dan Edit Gambar](#generate-dan-edit-gambar)
50
+ - [Lihat Proses Berpikir Model](#lihat-proses-berpikir-model)
51
+ - [Ambil Gambar dari Respons](#ambil-gambar-dari-respons)
52
+ - [Buat dan Edit Gambar](#buat-dan-edit-gambar)
53
53
  - [Ambil Video dan Audio](#ambil-video-dan-audio)
54
- - [Generate Konten dengan Ekstensi Gemini](#generate-konten-dengan-ekstensi-gemini)
55
- - [Periksa dan Ganti Kandidat Balasan](#periksa-dan-ganti-kandidat-balasan)
54
+ - [Gunakan Ekstensi Gemini](#gunakan-ekstensi-gemini)
55
+ - [Cek dan Ganti Kandidat Balasan](#cek-dan-ganti-kandidat-balasan)
56
56
  - [Deep Research](#deep-research)
57
57
  - [Status Akun](#status-akun)
58
58
  - [Quota dan Info Penggunaan](#quota-dan-info-penggunaan)
@@ -70,50 +70,50 @@ npm install gemini-reverse
70
70
 
71
71
  ## Autentikasi
72
72
 
73
- - Buka [gemini.google.com](https://gemini.google.com) dan masuk dengan akun Google Anda
74
- - Tekan F12 untuk membuka DevTools, buka tab `Application` → `Cookies` → `https://gemini.google.com`
73
+ - Buka [gemini.google.com](https://gemini.google.com) dan masuk dengan akun Google kamu
74
+ - Tekan F12 untuk buka DevTools, masuk ke tab `Application` → `Cookies` → `https://gemini.google.com`
75
75
  - Salin nilai `__Secure-1PSID` (dan opsional `__Secure-1PSIDTS`)
76
76
 
77
- > `__Secure-1PSIDTS` bersifat opsional — client akan mencoba memperbarui dan menyimpan cache-nya secara otomatis setelah inisialisasi pertama yang berhasil.
77
+ > `__Secure-1PSIDTS` bersifat opsional — client akan mencoba memperbarui dan menyimpannya secara otomatis setelah inisialisasi pertama berhasil.
78
78
 
79
79
  ## Penggunaan
80
80
 
81
81
  ### Inisialisasi
82
82
 
83
- Import package dan inisialisasi client dengan cookie Anda. Setelah inisialisasi berhasil, client akan memperbarui `__Secure-1PSIDTS` secara otomatis di latar belakang dengan jitter acak, dan memulai watchdog heartbeat untuk menjaga sesi tetap aktif.
83
+ Import package dan buat client dengan cookie kamu. Setelah berhasil diinisialisasi, client akan memperbarui `__Secure-1PSIDTS` otomatis di latar belakang dengan jitter acak, dan menjalankan heartbeat watchdog untuk menjaga sesi tetap aktif.
84
84
 
85
85
  ```js
86
86
  const { GeminiClient } = require('gemini-reverse');
87
87
 
88
88
  const client = new GeminiClient({
89
- secure_1psid: 'SECURE_1PSID_ANDA',
90
- secure_1psidts: 'SECURE_1PSIDTS_ANDA', // opsional
89
+ secure_1psid: 'SECURE_1PSID_KAMU',
90
+ secure_1psidts: 'SECURE_1PSIDTS_KAMU', // opsional
91
91
  proxy: null, // opsional, mis. 'http://host:port'
92
92
  });
93
93
 
94
94
  await client.init({
95
95
  timeout: 300000, // timeout request dalam ms, default 300000
96
96
  autoClose: false, // tutup client otomatis setelah tidak aktif
97
- closeDelay: 300000, // delay sebelum menutup dalam ms
98
- autoRefresh: true, // perbarui cookie + mulai activity watchdog
97
+ closeDelay: 300000, // jeda sebelum ditutup dalam ms
98
+ autoRefresh: true, // perbarui cookie + jalankan activity watchdog
99
99
  refreshInterval: 540000 // interval refresh cookie dalam ms
100
100
  });
101
101
  ```
102
102
 
103
- > `autoClose` dan `closeDelay` adalah argumen opsional untuk menutup client secara otomatis setelah tidak aktif dalam jangka waktu tertentu. Pada layanan yang selalu aktif seperti chatbot, disarankan untuk mengatur `autoClose` ke `true` dengan nilai `closeDelay` yang wajar untuk manajemen resource yang lebih baik.
103
+ > `autoClose` dan `closeDelay` berguna untuk menutup client otomatis saat tidak aktif. Pada layanan yang selalu berjalan seperti chatbot, disarankan set `autoClose: true` dengan nilai `closeDelay` yang masuk akal supaya penggunaan resource lebih efisien.
104
104
 
105
- ### Generate Konten
105
+ ### Buat Konten
106
106
 
107
- Ajukan pertanyaan satu-giliran dengan memanggil `generateContent`, yang mengembalikan objek `ModelOutput` berisi teks yang dihasilkan, gambar, pikiran, dan metadata percakapan.
107
+ Kirim pertanyaan satu arah dengan `generateContent`, yang mengembalikan objek `ModelOutput` berisi teks, gambar, pemikiran model, dan metadata percakapan.
108
108
 
109
109
  ```js
110
110
  const response = await client.generateContent({ prompt: 'Halo Dunia!' });
111
111
  console.log(response.text);
112
112
  ```
113
113
 
114
- ### Generate Konten dengan File
114
+ ### Buat Konten dengan File
115
115
 
116
- Gemini mendukung input file, termasuk gambar dan dokumen. Kirimkan array path file atau objek `Buffer` bersama prompt teks Anda.
116
+ Gemini mendukung input file seperti gambar dan dokumen. Sertakan daftar path file atau objek `Buffer` bersama prompt teks kamu.
117
117
 
118
118
  ```js
119
119
  const response = await client.generateContent({
@@ -125,7 +125,7 @@ console.log(response.text);
125
125
 
126
126
  ### Percakapan Multi-Giliran
127
127
 
128
- Gunakan `startChat` untuk membuat objek `ChatSession` dan kirim pesan melaluinya. Riwayat percakapan ditangani secara otomatis dan diperbarui setiap giliran.
128
+ Pakai `startChat` untuk membuat `ChatSession` dan kirim pesan lewat sesi itu. Riwayat percakapan dikelola otomatis dan diperbarui tiap giliran.
129
129
 
130
130
  ```js
131
131
  const chat = client.startChat();
@@ -134,12 +134,12 @@ const res1 = await chat.sendMessage({ prompt: 'Nama saya Alice.' });
134
134
  console.log(res1.text);
135
135
 
136
136
  const res2 = await chat.sendMessage({ prompt: 'Siapa nama saya?' });
137
- console.log(res2.text); // mengingat konteks
137
+ console.log(res2.text); // mengingat konteks sebelumnya
138
138
  ```
139
139
 
140
140
  ### Lanjutkan Percakapan Sebelumnya
141
141
 
142
- Kirimkan metadata `ChatSession` sebelumnya ke `startChat` untuk melanjutkan percakapan. Anda dapat menyimpan metadata ke file atau database untuk memulihkannya setelah proses di-restart.
142
+ Masukkan metadata dari `ChatSession` sebelumnya ke `startChat` untuk melanjutkan percakapan. Metadata bisa disimpan ke file atau database agar bisa dipulihkan setelah proses di-restart.
143
143
 
144
144
  ```js
145
145
  const chat = client.startChat();
@@ -157,7 +157,7 @@ console.log(response.text);
157
157
 
158
158
  ### Baca Riwayat Percakapan
159
159
 
160
- Ambil riwayat percakapan lengkap dengan memanggil `readChat` menggunakan ID chat. Mengembalikan objek `ChatHistory` berisi daftar objek `ChatTurn` dari terbaru ke terlama.
160
+ Ambil riwayat percakapan lengkap dengan `readChat` menggunakan ID chat. Mengembalikan objek `ChatHistory` berisi daftar `ChatTurn` dari terbaru ke terlama.
161
161
 
162
162
  ```js
163
163
  const chat = client.startChat();
@@ -171,7 +171,7 @@ if (history) {
171
171
  }
172
172
  ```
173
173
 
174
- Anda juga bisa membaca riwayat langsung dari sesi:
174
+ Kamu juga bisa baca riwayat langsung dari sesi:
175
175
 
176
176
  ```js
177
177
  const history = await chat.readHistory(10); // ambil 10 giliran terakhir
@@ -179,7 +179,7 @@ const history = await chat.readHistory(10); // ambil 10 giliran terakhir
179
179
 
180
180
  ### Daftar Chat Terbaru
181
181
 
182
- Gunakan `listChats` untuk mendapatkan daftar sesi chat terbaru yang di-cache saat inisialisasi.
182
+ Pakai `listChats` untuk mendapatkan daftar sesi chat terbaru yang di-cache saat inisialisasi.
183
183
 
184
184
  ```js
185
185
  const chats = client.listChats();
@@ -192,7 +192,7 @@ if (chats) {
192
192
 
193
193
  ### Hapus Percakapan
194
194
 
195
- Hapus chat tertentu dari riwayat Gemini di server dengan memanggil `deleteChat` menggunakan ID chat.
195
+ Hapus chat tertentu dari riwayat Gemini di server dengan `deleteChat` menggunakan ID chat.
196
196
 
197
197
  ```js
198
198
  const chat = client.startChat();
@@ -204,7 +204,7 @@ console.log(`Chat dihapus: ${chat.cid}`);
204
204
 
205
205
  ### Mode Sementara
206
206
 
207
- Kirimkan `temporary: true` ke `generateContent` atau `sendMessage` agar percakapan tidak tersimpan ke riwayat Gemini.
207
+ Tambahkan `temporary: true` ke `generateContent` atau `sendMessage` supaya percakapan tidak tersimpan ke riwayat Gemini.
208
208
 
209
209
  ```js
210
210
  const response = await client.generateContent({
@@ -213,7 +213,7 @@ const response = await client.generateContent({
213
213
  });
214
214
  console.log(response.text);
215
215
 
216
- // Juga berfungsi dalam sesi chat
216
+ // Juga bisa dipakai di dalam sesi chat
217
217
  const chat = client.startChat();
218
218
  await chat.sendMessage({ prompt: 'Cuaca hari ini cerah.', temporary: false });
219
219
  const res2 = await chat.sendMessage({ prompt: 'Apa pesan terakhir saya?', temporary: true });
@@ -222,18 +222,18 @@ console.log(res2.text);
222
222
 
223
223
  ### Mode Streaming
224
224
 
225
- Untuk respons yang panjang, gunakan mode streaming untuk menerima output parsial saat dihasilkan. Respons menggunakan `StreamingFrameParser` stateful secara internal sehingga frame parsial di-buffer secara efisien. Atribut `text_delta` hanya berisi **karakter baru** sejak yield terakhir.
225
+ Untuk respons yang panjang, pakai mode streaming agar output diterima secara bertahap. Di balik layar, respons menggunakan `StreamingFrameParser` stateful sehingga frame parsial di-buffer dengan efisien. Atribut `text_delta` hanya berisi **karakter baru** sejak yield terakhir.
226
226
 
227
227
  ```js
228
228
  for await (const chunk of client.generateContentStream({
229
- prompt: 'Apa perbedaan antara promise dan async/await?',
229
+ prompt: 'Apa bedanya promise dengan async/await?',
230
230
  })) {
231
231
  process.stdout.write(chunk.text_delta);
232
232
  }
233
233
  console.log();
234
234
  ```
235
235
 
236
- Streaming juga berfungsi dalam sesi chat:
236
+ Streaming juga bisa dipakai di dalam sesi chat:
237
237
 
238
238
  ```js
239
239
  const chat = client.startChat();
@@ -244,13 +244,13 @@ for await (const chunk of chat.sendMessageStream({ prompt: 'Ceritakan sebuah kis
244
244
 
245
245
  ### Extended Thinking
246
246
 
247
- Kirimkan `extended_thinking: true` untuk mengaktifkan mode penalaran yang lebih dalam. Model akan meluangkan lebih banyak waktu untuk merencanakan sebelum merespons. Didukung pada model tier Pro dan Advanced.
247
+ Tambahkan `extended_thinking: true` untuk mengaktifkan mode penalaran mendalam. Model akan meluangkan lebih banyak waktu berpikir sebelum menjawab. Didukung pada model tier Pro dan Advanced.
248
248
 
249
249
  ```js
250
250
  const { Model } = require('gemini-reverse');
251
251
 
252
252
  const response = await client.generateContent({
253
- prompt: 'Selesaikan langkah demi langkah: Jika sebuah kereta melaju 120 km/jam dan harus menempuh 450 km, berapa lama waktu yang dibutuhkan?',
253
+ prompt: 'Selesaikan langkah demi langkah: Kereta melaju 120 km/jam dan harus menempuh 450 km. Berapa lama waktu yang dibutuhkan?',
254
254
  model: Model.ADVANCED_PRO,
255
255
  extended_thinking: true,
256
256
  });
@@ -261,7 +261,7 @@ if (response.thoughts) {
261
261
  console.log('Jawaban:', response.text);
262
262
  ```
263
263
 
264
- Juga berfungsi dalam streaming dan chat:
264
+ Juga bisa dipakai di streaming dan chat:
265
265
 
266
266
  ```js
267
267
  const chat = client.startChat({ model: Model.ADVANCED_FLASH });
@@ -274,21 +274,21 @@ console.log(res.text);
274
274
 
275
275
  ### Pilih Model Bahasa
276
276
 
277
- Tentukan model bahasa yang digunakan dengan mengoper argumen `model`. Model tersedia ditemukan secara dinamis saat inisialisasi berdasarkan tier akun Anda.
277
+ Tentukan model yang akan dipakai dengan mengisi argumen `model`. Model yang tersedia ditemukan secara dinamis saat inisialisasi berdasarkan tier akun kamu.
278
278
 
279
279
  ```js
280
280
  const { Model } = require('gemini-reverse');
281
281
 
282
- // Menggunakan konstanta bawaan
282
+ // Pakai konstanta bawaan
283
283
  const response1 = await client.generateContent({
284
- prompt: 'Apa versi model Anda?',
284
+ prompt: 'Apa versi model kamu?',
285
285
  model: Model.BASIC_FLASH,
286
286
  });
287
287
 
288
- // Menggunakan string nama model (case-insensitive)
288
+ // Pakai nama model sebagai string (tidak case-sensitive)
289
289
  const chat = client.startChat({ model: 'gemini-3-pro' });
290
290
 
291
- // Menggunakan dict model header kustom
291
+ // Pakai model header kustom
292
292
  const chat2 = client.startChat({
293
293
  model: {
294
294
  model_name: 'kustom',
@@ -301,13 +301,13 @@ const chat2 = client.startChat({
301
301
  });
302
302
  ```
303
303
 
304
- **Konstanta model bawaan:**
304
+ **Daftar konstanta model:**
305
305
 
306
- | Konstanta | `model_name` | Catatan |
306
+ | Konstanta | `model_name` | Keterangan |
307
307
  |---|---|---|
308
- | `Model.UNSPECIFIED` | `unspecified` | Default, Gemini memilih sendiri |
308
+ | `Model.UNSPECIFIED` | `unspecified` | Default, Gemini yang memilih |
309
309
  | `Model.BASIC_PRO` | `gemini-3-pro` | Tier gratis |
310
- | `Model.BASIC_FLASH` | `gemini-3-flash` | Tier gratis, tercepat |
310
+ | `Model.BASIC_FLASH` | `gemini-3-flash` | Tier gratis, paling cepat |
311
311
  | `Model.BASIC_LITE` | `gemini-3-lite` | Tier gratis, ringan |
312
312
  | `Model.PLUS_PRO` | `gemini-3-pro-plus` | Tier Plus |
313
313
  | `Model.PLUS_FLASH` | `gemini-3-flash-plus` | Tier Plus |
@@ -318,7 +318,7 @@ const chat2 = client.startChat({
318
318
 
319
319
  ### Daftar Model Tersedia
320
320
 
321
- Client menemukan model mana yang dapat diakses akun Anda secara dinamis saat inisialisasi. Gunakan `listModels` untuk memeriksanya.
321
+ Client otomatis menemukan model yang bisa diakses akun kamu saat inisialisasi. Pakai `listModels` untuk melihatnya.
322
322
 
323
323
  ```js
324
324
  await client.init();
@@ -332,48 +332,48 @@ if (models) {
332
332
  }
333
333
  ```
334
334
 
335
- ### Terapkan System Prompt dengan Gemini Gems
335
+ ### Pakai System Prompt dengan Gemini Gems
336
336
 
337
- System prompt dapat diterapkan pada percakapan melalui [Gemini Gems](https://gemini.google.com/gems/view). Kirimkan argumen `gem` ke `generateContent` atau `startChat` — bisa berupa objek `Gem` atau string ID gem.
337
+ System prompt bisa diterapkan ke percakapan lewat [Gemini Gems](https://gemini.google.com/gems/view). Isi argumen `gem` di `generateContent` atau `startChat` — bisa berupa objek `Gem` maupun string ID gem.
338
338
 
339
339
  ```js
340
- // Ambil semua gems untuk akun
340
+ // Ambil semua gems dari akun
341
341
  await client.fetchGems();
342
342
  const gems = client.gems;
343
343
 
344
- // Dapatkan gem tertentu
344
+ // Cari gem tertentu
345
345
  const codingPartner = gems.get({ name: 'Coding partner' });
346
346
 
347
347
  const response = await client.generateContent({
348
- prompt: 'Apa system prompt Anda?',
348
+ prompt: 'Apa system prompt kamu?',
349
349
  gem: codingPartner,
350
350
  });
351
351
  console.log(response.text);
352
352
 
353
- // Gunakan gem dalam chat multi-giliran
353
+ // Pakai gem di percakapan multi-giliran
354
354
  const chat = client.startChat({ gem: codingPartner });
355
355
  const res2 = await chat.sendMessage({ prompt: 'Bantu saya menulis binary search.' });
356
356
  console.log(res2.text);
357
357
  ```
358
358
 
359
- > Ada beberapa gems sistem bawaan yang tersembunyi secara default. Gunakan `fetchGems({ includeHidden: true })` untuk menyertakannya.
359
+ > Ada beberapa gem bawaan yang tersembunyi secara default. Pakai `fetchGems({ includeHidden: true })` untuk menyertakannya.
360
360
 
361
361
  ### Kelola Custom Gems
362
362
 
363
- Anda dapat membuat, memperbarui, dan menghapus custom gems secara programatik. Gems sistem bawaan tidak dapat dimodifikasi.
363
+ Kamu bisa membuat, mengedit, dan menghapus custom gem secara programatik. Gem bawaan sistem tidak bisa dimodifikasi.
364
364
 
365
365
  #### Buat Custom Gem
366
366
 
367
367
  ```js
368
368
  const newGem = await client.createGem({
369
369
  name: 'Tutor Python',
370
- prompt: 'Anda adalah tutor pemrograman Python yang membantu. Selalu berikan contoh kode yang dapat dijalankan.',
371
- description: 'Gem khusus untuk pemrograman Python',
370
+ prompt: 'Kamu adalah tutor Python yang membantu. Selalu sertakan contoh kode yang bisa langsung dijalankan.',
371
+ description: 'Gem khusus untuk belajar Python',
372
372
  });
373
373
 
374
374
  console.log(`Dibuat: ${newGem.id}`);
375
375
 
376
- // Gunakan gem baru segera
376
+ // Langsung pakai gem yang baru dibuat
377
377
  const response = await client.generateContent({
378
378
  prompt: 'Jelaskan list comprehension.',
379
379
  gem: newGem,
@@ -381,9 +381,9 @@ const response = await client.generateContent({
381
381
  console.log(response.text);
382
382
  ```
383
383
 
384
- #### Perbarui Gem yang Ada
384
+ #### Edit Gem yang Ada
385
385
 
386
- > Saat memperbarui gem, semua parameter (`name`, `prompt`, `description`) harus disediakan meskipun hanya satu yang berubah.
386
+ > Saat mengedit gem, semua parameter (`name`, `prompt`, `description`) harus diisi meskipun hanya satu yang berubah.
387
387
 
388
388
  ```js
389
389
  await client.fetchGems();
@@ -392,7 +392,7 @@ const pythonTutor = client.gems.get({ name: 'Tutor Python' });
392
392
  const updatedGem = await client.updateGem({
393
393
  gem: pythonTutor,
394
394
  name: 'Tutor Python Lanjutan',
395
- prompt: 'Anda adalah tutor pemrograman Python ahli. Fokus pada performa dan praktik terbaik.',
395
+ prompt: 'Kamu adalah tutor Python ahli. Fokus pada performa dan best practice.',
396
396
  description: 'Asisten pemrograman Python tingkat lanjut',
397
397
  });
398
398
 
@@ -405,13 +405,13 @@ console.log(`Diperbarui: ${updatedGem.id}`);
405
405
  await client.fetchGems();
406
406
  const gemToDelete = client.gems.get({ name: 'Tutor Python Lanjutan' });
407
407
 
408
- await client.deleteGem(gemToDelete); // bisa juga kirim string ID gem
408
+ await client.deleteGem(gemToDelete); // bisa juga isi string ID gem
409
409
  console.log(`Dihapus: ${gemToDelete.name}`);
410
410
  ```
411
411
 
412
- ### Ambil Proses Berpikir Model
412
+ ### Lihat Proses Berpikir Model
413
413
 
414
- Saat menggunakan model yang mendukung kemampuan berpikir, proses penalaran internal model diekspos melalui `response.thoughts`.
414
+ Saat memakai model dengan kemampuan berpikir, proses penalaran internalnya bisa diakses lewat `response.thoughts`.
415
415
 
416
416
  ```js
417
417
  const response = await client.generateContent({
@@ -420,17 +420,17 @@ const response = await client.generateContent({
420
420
  });
421
421
 
422
422
  if (response.thoughts) {
423
- console.log('Pemikiran:', response.thoughts);
423
+ console.log('Proses berpikir:', response.thoughts);
424
424
  }
425
425
  console.log('Jawaban:', response.text);
426
426
  ```
427
427
 
428
- ### Ambil Gambar dalam Respons
428
+ ### Ambil Gambar dari Respons
429
429
 
430
- Gambar dalam respons disimpan sebagai daftar objek `Image` yang dapat diakses melalui `response.images`. Setiap gambar memiliki `url`, `title`, dan deskripsi `alt`.
430
+ Gambar dalam respons tersimpan sebagai daftar objek `Image` yang bisa diakses lewat `response.images`. Tiap gambar punya `url`, `title`, dan deskripsi `alt`.
431
431
 
432
432
  ```js
433
- const response = await client.generateContent({ prompt: 'Kirimkan beberapa foto kucing.' });
433
+ const response = await client.generateContent({ prompt: 'Kirimin beberapa foto kucing dong.' });
434
434
 
435
435
  for (const image of response.images) {
436
436
  console.log(`${image.title}: ${image.url}`);
@@ -438,15 +438,15 @@ for (const image of response.images) {
438
438
  }
439
439
  ```
440
440
 
441
- ### Generate dan Edit Gambar
441
+ ### Buat dan Edit Gambar
442
442
 
443
- Minta Gemini untuk menghasilkan atau mengedit gambar menggunakan bahasa natural. Gambar yang dihasilkan dikembalikan sebagai objek `GeneratedImage` dan dapat disimpan ke disk.
443
+ Minta Gemini untuk membuat atau mengedit gambar menggunakan bahasa natural. Gambar yang dihasilkan dikembalikan sebagai objek `GeneratedImage` dan bisa disimpan ke disk.
444
444
 
445
- > Google memiliki batasan ketersediaan pembuatan gambar yang bervariasi menurut wilayah dan jenis akun. Pengguna di bawah 18 tahun tidak dapat menggunakan fitur ini.
445
+ > Google membatasi ketersediaan fitur pembuatan gambar berdasarkan wilayah dan jenis akun. Pengguna di bawah 18 tahun tidak dapat menggunakan fitur ini.
446
446
 
447
447
  ```js
448
448
  const response = await client.generateContent({
449
- prompt: 'Buat gambar realistis kucing berpakaian astronot.',
449
+ prompt: 'Buatkan gambar realistis kucing pakai baju astronot.',
450
450
  });
451
451
 
452
452
  for (let i = 0; i < response.images.length; i++) {
@@ -456,22 +456,22 @@ for (let i = 0; i < response.images.length; i++) {
456
456
  filename: `kucing_angkasa_${i}.png`,
457
457
  verbose: true,
458
458
  });
459
- console.log(`Disimpan ke: ${savedPath}`);
459
+ console.log(`Tersimpan di: ${savedPath}`);
460
460
  }
461
461
  ```
462
462
 
463
- > Saat meminta Gemini "mengirim" gambar, ia mengembalikan gambar web (`WebImage`). Saat meminta "menghasilkan" gambar, ia mengembalikan gambar yang dihasilkan AI (`GeneratedImage`). Keduanya dikategorikan otomatis di `response.images`.
463
+ > Kalau kamu minta Gemini "mengirimkan" gambar, yang dikembalikan adalah gambar dari web (`WebImage`). Kalau minta "membuat" gambar, yang dikembalikan adalah gambar buatan AI (`GeneratedImage`). Keduanya dikategorikan otomatis di `response.images`.
464
464
 
465
465
  ### Ambil Video dan Audio
466
466
 
467
- Gemini dapat menghasilkan video pendek dan audio/musik. Dikembalikan sebagai objek `GeneratedVideo` dan `GeneratedMedia` di `response.videos` dan `response.media`.
467
+ Gemini bisa membuat video pendek dan audio/musik. Hasilnya dikembalikan sebagai objek `GeneratedVideo` dan `GeneratedMedia` di `response.videos` dan `response.media`.
468
468
 
469
- > Anda mungkin memerlukan langganan Gemini aktif untuk mengakses pembuatan video dan audio.
469
+ > Fitur ini mungkin membutuhkan langganan Gemini aktif.
470
470
 
471
471
  ```js
472
- // Generate video
472
+ // Buat video
473
473
  const videoResponse = await client.generateContent({
474
- prompt: 'Buat video pendek ombak di pantai.',
474
+ prompt: 'Buatkan video pendek ombak di pantai.',
475
475
  });
476
476
 
477
477
  for (const video of videoResponse.videos) {
@@ -480,9 +480,9 @@ for (const video of videoResponse.videos) {
480
480
  console.log('Thumbnail:', result.video_thumbnail);
481
481
  }
482
482
 
483
- // Generate audio/musik
483
+ // Buat audio/musik
484
484
  const mediaResponse = await client.generateContent({
485
- prompt: 'Buat melodi piano yang menenangkan.',
485
+ prompt: 'Buatkan melodi piano yang menenangkan.',
486
486
  });
487
487
 
488
488
  for (const media of mediaResponse.media) {
@@ -493,17 +493,17 @@ for (const media of mediaResponse.media) {
493
493
  }
494
494
  ```
495
495
 
496
- > `GeneratedMedia.save()` menerima parameter `downloadType`: `"audio"`, `"video"`, atau `"both"` (default). Metode save akan polling otomatis jika konten masih dalam proses generate (HTTP 206).
496
+ > `GeneratedMedia.save()` menerima parameter `downloadType`: `"audio"`, `"video"`, atau `"both"` (default). Kalau konten masih dalam proses dibuat, metode ini akan otomatis polling sampai selesai (HTTP 206).
497
497
 
498
- ### Generate Konten dengan Ekstensi Gemini
498
+ ### Gunakan Ekstensi Gemini
499
499
 
500
- Untuk menggunakan ekstensi Gemini (Gmail, YouTube, dll.), Anda harus mengaktifkannya terlebih dahulu di [situs Gemini](https://gemini.google.com/extensions). Referensikan dalam prompt dengan awalan `@` atau dalam bahasa natural.
500
+ Untuk memakai ekstensi Gemini (Gmail, YouTube, dll.), aktifkan dulu di [situs Gemini](https://gemini.google.com/extensions). Setelah itu tinggal panggil lewat prompt dengan awalan `@` atau dalam bahasa natural.
501
501
 
502
- > Anda harus mengaktifkan Gemini Apps Activity di akun untuk menggunakan ekstensi.
502
+ > Pastikan Gemini Apps Activity sudah aktif di akun kamu.
503
503
 
504
504
  ```js
505
505
  const gmailResponse = await client.generateContent({
506
- prompt: '@Gmail Apa pesan terbaru di kotak masuk saya?',
506
+ prompt: '@Gmail Apa pesan terbaru di inbox saya?',
507
507
  });
508
508
  console.log(gmailResponse.text);
509
509
 
@@ -513,24 +513,24 @@ const youtubeResponse = await client.generateContent({
513
513
  console.log(youtubeResponse.text);
514
514
  ```
515
515
 
516
- ### Periksa dan Ganti Kandidat Balasan
516
+ ### Cek dan Ganti Kandidat Balasan
517
517
 
518
- Respons Gemini terkadang berisi beberapa kandidat balasan dengan konten yang berbeda. Anda dapat memeriksa semua kandidat dan memilih satu untuk melanjutkan alur percakapan.
518
+ Kadang respons Gemini berisi beberapa kandidat balasan dengan konten yang berbeda. Kamu bisa melihat semua kandidat dan memilih salah satu untuk melanjutkan percakapan.
519
519
 
520
520
  ```js
521
521
  const chat = client.startChat();
522
522
  const response = await chat.sendMessage({ prompt: 'Rekomendasikan buku fiksi ilmiah.' });
523
523
 
524
- // Daftar semua kandidat
524
+ // Lihat semua kandidat
525
525
  response.candidates.forEach((candidate, i) => {
526
526
  console.log(`[${i}] ${candidate.text.slice(0, 80)}...`);
527
527
  });
528
528
 
529
529
  if (response.candidates.length > 1) {
530
- // Pilih kandidat kedua untuk dilanjutkan
530
+ // Pilih kandidat kedua
531
531
  chat.chooseCandidate(1);
532
532
 
533
- const followup = await chat.sendMessage({ prompt: 'Ceritakan lebih lanjut tentangnya.' });
533
+ const followup = await chat.sendMessage({ prompt: 'Ceritakan lebih lanjut.' });
534
534
  console.log(followup.text);
535
535
  } else {
536
536
  console.log('Hanya ada satu kandidat.');
@@ -539,15 +539,15 @@ if (response.candidates.length > 1) {
539
539
 
540
540
  ### Deep Research
541
541
 
542
- Fitur deep research Gemini adalah agen otonom yang menjelajahi web, menganalisis sumber, dan menghasilkan laporan komprehensif.
542
+ Fitur deep research Gemini adalah agen otonom yang menjelajah web, menganalisis sumber, dan menghasilkan laporan komprehensif.
543
543
 
544
- > Anda mungkin memerlukan langganan Gemini aktif untuk mengakses deep research.
544
+ > Fitur ini mungkin membutuhkan langganan Gemini aktif.
545
545
 
546
- **Metode satu panggilan cepat:**
546
+ **Cara cepat — satu pemanggilan:**
547
547
 
548
548
  ```js
549
549
  const result = await client.deepResearch(
550
- 'Bandingkan 3 penyedia cloud teratas dan penawaran AI mereka',
550
+ 'Bandingkan 3 penyedia cloud terbesar dan fitur AI mereka',
551
551
  10000, // interval polling dalam ms
552
552
  600000, // timeout dalam ms
553
553
  (status) => console.log(`Status: ${status.state} — ${status.notes.slice(0, 1).join(', ')}`),
@@ -557,12 +557,12 @@ console.log(`Selesai: ${result.done}`);
557
557
  console.log(result.text);
558
558
  ```
559
559
 
560
- **Alur kerja langkah demi langkah** untuk kontrol lebih:
560
+ **Alur langkah demi langkah** untuk kontrol lebih penuh:
561
561
 
562
562
  ```js
563
- // Langkah 1: Buat rencana penelitian
563
+ // Langkah 1: Buat rencana riset
564
564
  const plan = await client.createDeepResearchPlan(
565
- 'Apa kemajuan terbaru dalam komputasi kuantum?'
565
+ 'Apa perkembangan terbaru dalam komputasi kuantum?'
566
566
  );
567
567
 
568
568
  console.log(`Judul: ${plan.title}`);
@@ -571,11 +571,11 @@ for (const step of plan.steps) {
571
571
  console.log(` - ${step}`);
572
572
  }
573
573
 
574
- // Langkah 2: Mulai penelitian
574
+ // Langkah 2: Mulai riset
575
575
  const startOutput = await client.startDeepResearch(plan);
576
- console.log('Penelitian dimulai:', startOutput.text.slice(0, 100));
576
+ console.log('Riset dimulai:', startOutput.text.slice(0, 100));
577
577
 
578
- // Langkah 3: Poll hingga selesai
578
+ // Langkah 3: Tunggu sampai selesai
579
579
  const result = await client.waitForDeepResearch(
580
580
  plan,
581
581
  10000, // interval polling dalam ms
@@ -588,7 +588,7 @@ console.log(result.text);
588
588
 
589
589
  ### Status Akun
590
590
 
591
- Client mendeteksi tier kemampuan akun Anda saat inisialisasi dan mengeksposnya melalui `client.accountStatus`.
591
+ Client mendeteksi tier akun kamu saat inisialisasi dan menyimpannya di `client.accountStatus`.
592
592
 
593
593
  ```js
594
594
  const { AccountStatus } = require('gemini-reverse');
@@ -596,11 +596,11 @@ const { AccountStatus } = require('gemini-reverse');
596
596
  await client.init();
597
597
 
598
598
  if (client.accountStatus === AccountStatus.AVAILABLE) {
599
- console.log('Akun terotorisasi penuh.');
599
+ console.log('Akun aktif dan bisa digunakan.');
600
600
  } else if (client.accountStatus === AccountStatus.UNAUTHENTICATED) {
601
- console.error('Cookie kedaluwarsa atau tidak valid.');
601
+ console.error('Cookie sudah kedaluwarsa atau tidak valid.');
602
602
  } else if (client.accountStatus === AccountStatus.LOCATION_REJECTED) {
603
- console.error('Gemini tidak tersedia di wilayah Anda.');
603
+ console.error('Gemini tidak tersedia di wilayah kamu.');
604
604
  } else {
605
605
  console.warn(`Status akun: ${client.accountStatus.name} — ${client.accountStatus.description}`);
606
606
  }
@@ -608,22 +608,22 @@ if (client.accountStatus === AccountStatus.AVAILABLE) {
608
608
 
609
609
  **Semua nilai status akun:**
610
610
 
611
- | Konstanta | Kode | Deskripsi |
611
+ | Konstanta | Kode | Keterangan |
612
612
  |---|---|---|
613
- | `AccountStatus.AVAILABLE` | 1000 | Akun terotorisasi dan memiliki akses normal |
614
- | `AccountStatus.ACCESS_TEMPORARILY_UNAVAILABLE` | 1014 | Akses dibatasi, mungkin wilayah/sementara |
613
+ | `AccountStatus.AVAILABLE` | 1000 | Akun aktif dan punya akses normal |
614
+ | `AccountStatus.ACCESS_TEMPORARILY_UNAVAILABLE` | 1014 | Akses dibatasi sementara, mungkin karena wilayah |
615
615
  | `AccountStatus.UNAUTHENTICATED` | 1016 | Cookie kedaluwarsa atau tidak valid |
616
616
  | `AccountStatus.ACCOUNT_REJECTED` | 1021 | Akses akun ditolak |
617
- | `AccountStatus.ACCOUNT_UNTRUSTED` | 1033 | Tidak lulus pemeriksaan keamanan/kepercayaan |
618
- | `AccountStatus.TOS_PENDING` | 1040 | Harus menerima Syarat Layanan terbaru |
619
- | `AccountStatus.TOS_OUT_OF_DATE` | 1042 | Syarat Layanan sudah usang |
617
+ | `AccountStatus.ACCOUNT_UNTRUSTED` | 1033 | Tidak lolos pemeriksaan keamanan |
618
+ | `AccountStatus.TOS_PENDING` | 1040 | Perlu menerima Syarat Layanan terbaru |
619
+ | `AccountStatus.TOS_OUT_OF_DATE` | 1042 | Syarat Layanan sudah tidak berlaku |
620
620
  | `AccountStatus.ACCOUNT_REJECTED_BY_GUARDIAN` | 1054 | Diblokir oleh orang tua atau wali |
621
- | `AccountStatus.GUARDIAN_APPROVAL_REQUIRED` | 1057 | Memerlukan persetujuan orang tua |
622
- | `AccountStatus.LOCATION_REJECTED` | 1060 | Tidak tersedia di negara/wilayah Anda |
621
+ | `AccountStatus.GUARDIAN_APPROVAL_REQUIRED` | 1057 | Butuh persetujuan orang tua |
622
+ | `AccountStatus.LOCATION_REJECTED` | 1060 | Tidak tersedia di negara/wilayah kamu |
623
623
 
624
624
  ### Quota dan Info Penggunaan
625
625
 
626
- Setelah inisialisasi, client mengambil batas quota akun dan metrik penggunaan komputasi secara otomatis. Akses melalui `client.quotas`, `client.usageInfo`, dan `client.abuseStatus`.
626
+ Setelah inisialisasi, client otomatis mengambil batas quota dan data penggunaan akun. Hasilnya bisa diakses lewat `client.quotas`, `client.usageInfo`, dan `client.abuseStatus`.
627
627
 
628
628
  ```js
629
629
  await client.init();
@@ -632,18 +632,18 @@ await client.init();
632
632
  const quotas = client.quotas;
633
633
  for (const [id, q] of Object.entries(quotas)) {
634
634
  if (q.label) {
635
- const remaining = q.remaining !== null ? `${q.remaining}/${q.total}` : 'tak terbatas';
635
+ const remaining = q.remaining !== null ? `${q.remaining}/${q.total}` : 'tidak terbatas';
636
636
  console.log(`${q.label}: ${remaining} kredit (${q.usage_percentage?.toFixed(1) ?? '?'}% terpakai)`);
637
637
  }
638
638
  }
639
639
 
640
- // Penggunaan komputasi (jendela 5 jam dan mingguan)
640
+ // Data penggunaan komputasi (periode 5 jam dan mingguan)
641
641
  const usage = client.usageInfo;
642
642
  if (usage.tier) {
643
643
  console.log(`Tier akun: ${usage.tier.label}`);
644
644
  }
645
645
  if (usage.current_5h) {
646
- console.log(`Jendela 5 jam: ${usage.current_5h.remaining_credits} kredit tersisa (${usage.current_5h.usage_percentage}% terpakai)`);
646
+ console.log(`5 jam terakhir: ${usage.current_5h.remaining_credits} kredit tersisa (${usage.current_5h.usage_percentage}% terpakai)`);
647
647
  }
648
648
  if (usage.weekly) {
649
649
  console.log(`Mingguan: ${usage.weekly.remaining_credits} kredit tersisa`);
@@ -674,13 +674,13 @@ try {
674
674
  console.log(response.text);
675
675
  } catch (e) {
676
676
  if (e instanceof AuthError) {
677
- console.error('Cookie kedaluwarsa atau tidak valid. Perbarui cookie Anda.');
677
+ console.error('Cookie kedaluwarsa atau tidak valid. Perbarui cookie kamu.');
678
678
  } else if (e instanceof UsageLimitExceeded) {
679
679
  console.error('Batas penggunaan tercapai. Coba lagi nanti atau ganti model.');
680
680
  } else if (e instanceof TemporarilyBlocked) {
681
- console.error('IP diblokir sementara oleh Google. Coba gunakan proxy atau tunggu.');
681
+ console.error('IP diblokir sementara oleh Google. Coba pakai proxy atau tunggu sebentar.');
682
682
  } else if (e instanceof TimeoutError) {
683
- console.error('Request timeout. Coba tingkatkan nilai timeout di init().');
683
+ console.error('Request timeout. Coba naikkan nilai timeout di init().');
684
684
  } else if (e instanceof ModelInvalid) {
685
685
  console.error('Model tidak valid atau tidak tersedia. Coba model lain.');
686
686
  } else if (e instanceof APIError) {
@@ -693,7 +693,7 @@ try {
693
693
 
694
694
  ## Persistensi Cookie
695
695
 
696
- Jika aplikasi Anda berjalan di lingkungan container (mis. Docker), Anda dapat menyimpan cache cookie yang diperbarui otomatis ke volume dengan mengatur variabel environment `GEMINI_COOKIE_PATH` ke path yang dapat ditulis.
696
+ Kalau aplikasi kamu berjalan di container (mis. Docker), simpan cache cookie yang diperbarui otomatis ke volume dengan mengatur variabel environment `GEMINI_COOKIE_PATH` ke path yang bisa ditulis.
697
697
 
698
698
  ```yaml
699
699
  # docker-compose.yml
@@ -709,7 +709,7 @@ Secara default, cache disimpan di `utils/temp/` relatif terhadap direktori packa
709
709
 
710
710
  ## TypeScript
711
711
 
712
- Package ini menyertakan deklarasi TypeScript lengkap.
712
+ Package ini sudah menyertakan deklarasi TypeScript lengkap.
713
713
 
714
714
  ```ts
715
715
  import {
@@ -746,7 +746,7 @@ if (history) {
746
746
 
747
747
  const models: AvailableModel[] | null = client.listModels();
748
748
 
749
- // Akses quota dan usage setelah init
749
+ // Akses quota dan info penggunaan setelah init
750
750
  console.log(client.quotas);
751
751
  console.log(client.usageInfo);
752
752
  console.log(client.abuseStatus);
@@ -795,6 +795,6 @@ gemini-reverse/
795
795
 
796
796
  ---
797
797
 
798
- **Peringatan:** Ini adalah package tidak resmi dan tidak berafiliasi dengan atau didukung oleh Google. Autentikasi berbasis cookie mungkin tidak berfungsi jika Google mengubah API internalnya. Gunakan dengan risiko Anda sendiri.
798
+ **Disclaimer:** Ini adalah package tidak resmi dan tidak ada hubungannya dengan Google. Autentikasi berbasis cookie bisa saja berhenti bekerja kalau Google mengubah API internalnya. Gunakan dengan risiko sendiri.
799
799
 
800
800
  **Lisensi:** MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gemini-reverse",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Unofficial Node.js client for gemini.google.com — inspired by Gemini-API (Python). Supports streaming, chat sessions, gems, file uploads, and TypeScript.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",