gemini-reverse 1.0.5 → 1.0.7
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/README.md +96 -15
- package/client.js +287 -41
- package/components/chatMixin.js +1 -0
- package/components/gemMixin.js +2 -1
- package/constants.js +59 -23
- package/index.d.ts +9 -2
- package/index.js +2 -0
- package/package.json +1 -1
- package/types/availablemodel.js +32 -5
- package/types/candidate.js +16 -2
- package/types/video.js +4 -0
- package/utils/index.js +2 -1
- package/utils/parsing.js +109 -32
- package/utils/upload.js +17 -6
package/README.md
CHANGED
|
@@ -6,15 +6,18 @@ An unofficial Node.js client for [Google Gemini](https://gemini.google.com), ins
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Persistent Cookies** — Automatically refreshes cookies in the background. Optimized for always-on services.
|
|
9
|
+
- **Persistent Cookies** — Automatically refreshes cookies in the background with jitter to prevent synchronized requests. Optimized for always-on services.
|
|
10
10
|
- **Image Generation** — Natively supports generating and editing images with natural language.
|
|
11
11
|
- **Video & Audio Generation** — Supports generating videos and audio/music content natively.
|
|
12
12
|
- **Deep Research** — Full deep research workflow with plan creation, status polling, and result retrieval.
|
|
13
|
+
- **Extended Thinking** — Enables deeper reasoning mode on supported models.
|
|
13
14
|
- **System Prompt** — Supports customizing the model's system prompt with [Gemini Gems](https://gemini.google.com/gems/view).
|
|
14
15
|
- **Extension Support** — Supports generating content with Gemini extensions such as YouTube and Gmail.
|
|
15
16
|
- **Classified Outputs** — Categorizes text, thoughts, images, videos, and audio in the response.
|
|
16
|
-
- **Streaming Mode** — Supports stream generation, yielding partial outputs as they are generated.
|
|
17
|
+
- **Streaming Mode** — Supports stream generation with an incremental stateful frame parser, yielding partial outputs as they are generated.
|
|
17
18
|
- **Dynamic Model Discovery** — Automatically discovers available models from your account at initialization.
|
|
19
|
+
- **Quota & Usage Info** — Exposes account quota, compute usage, and abuse status after initialization.
|
|
20
|
+
- **Activity Watchdog** — Background heartbeat task that keeps the session alive automatically.
|
|
18
21
|
- **TypeScript Support** — Full TypeScript type declarations included out of the box.
|
|
19
22
|
|
|
20
23
|
## Table of Contents
|
|
@@ -34,6 +37,7 @@ An unofficial Node.js client for [Google Gemini](https://gemini.google.com), ins
|
|
|
34
37
|
- [Delete a Conversation](#delete-a-conversation)
|
|
35
38
|
- [Temporary Mode](#temporary-mode)
|
|
36
39
|
- [Streaming Mode](#streaming-mode)
|
|
40
|
+
- [Extended Thinking](#extended-thinking)
|
|
37
41
|
- [Select Language Model](#select-language-model)
|
|
38
42
|
- [List Available Models](#list-available-models)
|
|
39
43
|
- [Apply System Prompt with Gemini Gems](#apply-system-prompt-with-gemini-gems)
|
|
@@ -49,6 +53,7 @@ An unofficial Node.js client for [Google Gemini](https://gemini.google.com), ins
|
|
|
49
53
|
- [Check and Switch to Other Reply Candidates](#check-and-switch-to-other-reply-candidates)
|
|
50
54
|
- [Deep Research](#deep-research)
|
|
51
55
|
- [Account Status](#account-status)
|
|
56
|
+
- [Quota and Usage Info](#quota-and-usage-info)
|
|
52
57
|
- [Error Handling](#error-handling)
|
|
53
58
|
- [Cookie Persistence](#cookie-persistence)
|
|
54
59
|
- [TypeScript](#typescript)
|
|
@@ -73,7 +78,7 @@ npm install gemini-reverse
|
|
|
73
78
|
|
|
74
79
|
### Initialization
|
|
75
80
|
|
|
76
|
-
Import the package and initialize a client with your cookies. After a successful initialization, the client will automatically refresh `__Secure-1PSIDTS` in the background
|
|
81
|
+
Import the package and initialize a client with your cookies. After a successful initialization, the client will automatically refresh `__Secure-1PSIDTS` in the background with random jitter, and start a heartbeat watchdog to keep the session alive.
|
|
77
82
|
|
|
78
83
|
```js
|
|
79
84
|
const { GeminiClient } = require('gemini-reverse');
|
|
@@ -88,7 +93,7 @@ await client.init({
|
|
|
88
93
|
timeout: 300000, // request timeout in ms, default 300000
|
|
89
94
|
autoClose: false, // auto-close client after inactivity
|
|
90
95
|
closeDelay: 300000, // inactivity delay before closing in ms
|
|
91
|
-
autoRefresh: true, // auto-refresh cookies
|
|
96
|
+
autoRefresh: true, // auto-refresh cookies + start activity watchdog
|
|
92
97
|
refreshInterval: 540000 // cookie refresh interval in ms
|
|
93
98
|
});
|
|
94
99
|
```
|
|
@@ -215,7 +220,7 @@ console.log(res2.text);
|
|
|
215
220
|
|
|
216
221
|
### Streaming Mode
|
|
217
222
|
|
|
218
|
-
For longer responses, use streaming mode to receive partial outputs as they are generated. The `text_delta` attribute contains only the **new characters** received since the last yield
|
|
223
|
+
For longer responses, use streaming mode to receive partial outputs as they are generated. The response uses a stateful `StreamingFrameParser` internally, so partial frames are buffered efficiently across chunks without rescanning. The `text_delta` attribute contains only the **new characters** received since the last yield.
|
|
219
224
|
|
|
220
225
|
```js
|
|
221
226
|
for await (const chunk of client.generateContentStream({
|
|
@@ -235,6 +240,36 @@ for await (const chunk of chat.sendMessageStream({ prompt: 'Tell me a long story
|
|
|
235
240
|
}
|
|
236
241
|
```
|
|
237
242
|
|
|
243
|
+
### Extended Thinking
|
|
244
|
+
|
|
245
|
+
Pass `extended_thinking: true` to enable deeper reasoning mode. This causes the model to spend more time planning before responding. Supported on Pro and Advanced tier models.
|
|
246
|
+
|
|
247
|
+
```js
|
|
248
|
+
const { Model } = require('gemini-reverse');
|
|
249
|
+
|
|
250
|
+
const response = await client.generateContent({
|
|
251
|
+
prompt: 'Solve this step by step: If a train travels at 120 km/h and needs to cover 450 km, how long does it take?',
|
|
252
|
+
model: Model.ADVANCED_PRO,
|
|
253
|
+
extended_thinking: true,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
if (response.thoughts) {
|
|
257
|
+
console.log('Thinking process:', response.thoughts);
|
|
258
|
+
}
|
|
259
|
+
console.log('Answer:', response.text);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Also works in streaming and chat:
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
const chat = client.startChat({ model: Model.ADVANCED_FLASH });
|
|
266
|
+
const res = await chat.sendMessage({
|
|
267
|
+
prompt: 'Explain the P vs NP problem.',
|
|
268
|
+
extended_thinking: true,
|
|
269
|
+
});
|
|
270
|
+
console.log(res.text);
|
|
271
|
+
```
|
|
272
|
+
|
|
238
273
|
### Select Language Model
|
|
239
274
|
|
|
240
275
|
Specify which language model to use by passing a `model` argument. Available models are discovered dynamically at init time based on your account tier.
|
|
@@ -248,7 +283,7 @@ const response1 = await client.generateContent({
|
|
|
248
283
|
model: Model.BASIC_FLASH,
|
|
249
284
|
});
|
|
250
285
|
|
|
251
|
-
// Using a model name string
|
|
286
|
+
// Using a model name string (case-insensitive)
|
|
252
287
|
const chat = client.startChat({ model: 'gemini-3-pro' });
|
|
253
288
|
|
|
254
289
|
// Using a custom model header dict
|
|
@@ -256,7 +291,9 @@ const chat2 = client.startChat({
|
|
|
256
291
|
model: {
|
|
257
292
|
model_name: 'custom',
|
|
258
293
|
model_header: {
|
|
259
|
-
'x-goog-ext-525001261-jspb': '[1,null,null,null,"MODEL_ID",null,null,0,[4],null,null,
|
|
294
|
+
'x-goog-ext-525001261-jspb': '[1,null,null,null,"MODEL_ID",null,null,0,[4,5,6,8],null,null,1,null,null,1]',
|
|
295
|
+
'x-goog-ext-73010989-jspb': '[0]',
|
|
296
|
+
'x-goog-ext-73010990-jspb': '[0,0,0]',
|
|
260
297
|
},
|
|
261
298
|
},
|
|
262
299
|
});
|
|
@@ -269,13 +306,13 @@ const chat2 = client.startChat({
|
|
|
269
306
|
| `Model.UNSPECIFIED` | `unspecified` | Default, lets Gemini choose |
|
|
270
307
|
| `Model.BASIC_PRO` | `gemini-3-pro` | Free tier |
|
|
271
308
|
| `Model.BASIC_FLASH` | `gemini-3-flash` | Free tier, fastest |
|
|
272
|
-
| `Model.
|
|
309
|
+
| `Model.BASIC_LITE` | `gemini-3-lite` | Free tier, lightweight |
|
|
273
310
|
| `Model.PLUS_PRO` | `gemini-3-pro-plus` | Plus tier |
|
|
274
311
|
| `Model.PLUS_FLASH` | `gemini-3-flash-plus` | Plus tier |
|
|
275
|
-
| `Model.
|
|
312
|
+
| `Model.PLUS_LITE` | `gemini-3-lite-plus` | Plus tier |
|
|
276
313
|
| `Model.ADVANCED_PRO` | `gemini-3-pro-advanced` | Advanced tier |
|
|
277
314
|
| `Model.ADVANCED_FLASH` | `gemini-3-flash-advanced` | Advanced tier |
|
|
278
|
-
| `Model.
|
|
315
|
+
| `Model.ADVANCED_LITE` | `gemini-3-lite-advanced` | Advanced tier |
|
|
279
316
|
|
|
280
317
|
### List Available Models
|
|
281
318
|
|
|
@@ -288,7 +325,7 @@ const models = client.listModels();
|
|
|
288
325
|
if (models) {
|
|
289
326
|
for (const model of models) {
|
|
290
327
|
console.log(`${model.model_id} → ${model.model_name || model.display_name}`);
|
|
291
|
-
console.log(` capacity: ${model.capacity}, advanced_only: ${model.advanced_only}`);
|
|
328
|
+
console.log(` capacity: ${model.capacity}, model_number: ${model.model_number}, advanced_only: ${model.advanced_only}`);
|
|
292
329
|
}
|
|
293
330
|
}
|
|
294
331
|
```
|
|
@@ -377,7 +414,7 @@ When using thinking-capable models, the model's internal reasoning is exposed vi
|
|
|
377
414
|
```js
|
|
378
415
|
const response = await client.generateContent({
|
|
379
416
|
prompt: 'What is 17 × 23?',
|
|
380
|
-
model: Model.
|
|
417
|
+
model: Model.BASIC_FLASH,
|
|
381
418
|
});
|
|
382
419
|
|
|
383
420
|
if (response.thoughts) {
|
|
@@ -582,6 +619,41 @@ if (client.accountStatus === AccountStatus.AVAILABLE) {
|
|
|
582
619
|
| `AccountStatus.GUARDIAN_APPROVAL_REQUIRED` | 1057 | Requires parental approval |
|
|
583
620
|
| `AccountStatus.LOCATION_REJECTED` | 1060 | Not available in your country/region |
|
|
584
621
|
|
|
622
|
+
### Quota and Usage Info
|
|
623
|
+
|
|
624
|
+
After initialization, the client fetches account quota limits and compute usage metrics automatically. Access them via `client.quotas`, `client.usageInfo`, and `client.abuseStatus`.
|
|
625
|
+
|
|
626
|
+
```js
|
|
627
|
+
await client.init();
|
|
628
|
+
|
|
629
|
+
// Quota limits (Flash, Pro, extra features)
|
|
630
|
+
const quotas = client.quotas;
|
|
631
|
+
for (const [id, q] of Object.entries(quotas)) {
|
|
632
|
+
if (q.label) {
|
|
633
|
+
const remaining = q.remaining !== null ? `${q.remaining}/${q.total}` : 'unlimited';
|
|
634
|
+
console.log(`${q.label}: ${remaining} credits (${q.usage_percentage?.toFixed(1) ?? '?'}% used)`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Compute usage (5-hour and weekly windows)
|
|
639
|
+
const usage = client.usageInfo;
|
|
640
|
+
if (usage.tier) {
|
|
641
|
+
console.log(`Account tier: ${usage.tier.label}`);
|
|
642
|
+
}
|
|
643
|
+
if (usage.current_5h) {
|
|
644
|
+
console.log(`5h window: ${usage.current_5h.remaining_credits} credits remaining (${usage.current_5h.usage_percentage}% used)`);
|
|
645
|
+
}
|
|
646
|
+
if (usage.weekly) {
|
|
647
|
+
console.log(`Weekly: ${usage.weekly.remaining_credits} credits remaining`);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Abuse status
|
|
651
|
+
const abuse = client.abuseStatus;
|
|
652
|
+
if (abuse) {
|
|
653
|
+
console.log(`Account clean: ${abuse.is_clean}`);
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
585
657
|
## Error Handling
|
|
586
658
|
|
|
587
659
|
```js
|
|
@@ -651,13 +723,17 @@ import {
|
|
|
651
723
|
AccountStatus,
|
|
652
724
|
DeepResearchPlan,
|
|
653
725
|
DeepResearchResult,
|
|
726
|
+
StreamingFrameParser,
|
|
654
727
|
} from 'gemini-reverse';
|
|
655
728
|
|
|
656
729
|
const client = new GeminiClient({ secure_1psid: '...' });
|
|
657
730
|
await client.init();
|
|
658
731
|
|
|
659
732
|
const chat: ChatSession = client.startChat({ model: 'gemini-3-flash' });
|
|
660
|
-
const response: ModelOutput = await chat.sendMessage({
|
|
733
|
+
const response: ModelOutput = await chat.sendMessage({
|
|
734
|
+
prompt: 'Hello!',
|
|
735
|
+
extended_thinking: false,
|
|
736
|
+
});
|
|
661
737
|
|
|
662
738
|
console.log(response.text);
|
|
663
739
|
|
|
@@ -667,6 +743,11 @@ if (history) {
|
|
|
667
743
|
}
|
|
668
744
|
|
|
669
745
|
const models: AvailableModel[] | null = client.listModels();
|
|
746
|
+
|
|
747
|
+
// Access quota and usage after init
|
|
748
|
+
console.log(client.quotas);
|
|
749
|
+
console.log(client.usageInfo);
|
|
750
|
+
console.log(client.abuseStatus);
|
|
670
751
|
```
|
|
671
752
|
|
|
672
753
|
## Project Structure
|
|
@@ -692,9 +773,9 @@ gemini-reverse/
|
|
|
692
773
|
│ └── video.js # Video, GeneratedVideo, GeneratedMedia
|
|
693
774
|
├── utils/
|
|
694
775
|
│ ├── accessToken.js # cookie handling & init request
|
|
695
|
-
│ ├── parsing.js # response parsing
|
|
776
|
+
│ ├── parsing.js # response parsing + StreamingFrameParser
|
|
696
777
|
│ ├── research.js # deep research payload extractors
|
|
697
|
-
│ ├── rotate.js # cookie rotation
|
|
778
|
+
│ ├── rotate.js # cookie rotation
|
|
698
779
|
│ └── upload.js # file upload helpers
|
|
699
780
|
└── components/
|
|
700
781
|
├── chatMixin.js # chat history methods
|