@8-/gemini-web-api 1.0.0 → 1.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@8-/gemini-web-api",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "OpenAI-compatible Gemini Web API reverse proxy running seamlessly on both Bun and Node.js with zero external dependencies.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -9,7 +9,9 @@
9
9
  },
10
10
  "scripts": {
11
11
  "start": "bun index.js",
12
- "start:node": "node index.js"
12
+ "start:node": "node index.js",
13
+ "test": "node --test",
14
+ "test:bun": "bun test"
13
15
  },
14
16
  "repository": {
15
17
  "type": "git",
@@ -0,0 +1,89 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+
4
+ export const HOST = process.env.HOST ?? "0.0.0.0",
5
+ PORT = parseInt(process.env.PORT ?? "7860", 10),
6
+ API_KEY = process.env.API_KEY ?? "",
7
+ ENABLE_THINKING = process.env.ENABLE_THINKING === "true",
8
+ INIT_URL = "https://gemini.google.com/app",
9
+ GEN_URL =
10
+ "https://gemini.google.com/_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate",
11
+ BATCH_URL = "https://gemini.google.com/_/BardChatUi/data/batchexecute",
12
+ USER_AGENT =
13
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
14
+ SALT = new TextEncoder().encode("saltysalt"),
15
+ IV = new Uint8Array(16).fill(32),
16
+ CORS_HEADERS = {
17
+ "Access-Control-Allow-Origin": "*",
18
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
19
+ "Access-Control-Allow-Headers": "*",
20
+ },
21
+ STATUS_OK = 200,
22
+ STATUS_NO_CONTENT = 204,
23
+ STATUS_BAD_REQUEST = 400,
24
+ STATUS_UNAUTHORIZED = 401,
25
+ STATUS_NOT_FOUND = 404,
26
+ STATUS_SERVER_ERR = 500,
27
+ ERR_MISSING_URL = 4001,
28
+ ERR_UNAUTHORIZED = 4011,
29
+ ERR_NOT_FOUND = 4041,
30
+ THINKING_LEVEL_DISABLED = 1,
31
+ THINKING_LEVEL_ENABLED = 2,
32
+ ROLE_ASSISTANT = "assistant",
33
+ ROLE_USER = "user",
34
+ ROLE_SYSTEM = "system",
35
+ ROLE_TOOL = "tool",
36
+ STOP_REASON_STOP = "stop",
37
+ STOP_REASON_TOOL_CALLS = "tool_calls",
38
+ TOOL_FENCE_OPEN = "```tool_call",
39
+ TOOL_FENCE_CLOSE = "```",
40
+ PAYLOAD_INNER_REQ_IDX = 0,
41
+ PAYLOAD_MODEL_HEADER_IDX = 1,
42
+ PAYLOAD_UUID_IDX = 2,
43
+ BROWSER_PATH_LI = [
44
+ {
45
+ db_path: join(homedir(), "Library/Application Support/Google/Chrome/Default/Cookies"),
46
+ account: "Chrome",
47
+ service: "Chrome Safe Storage",
48
+ },
49
+ {
50
+ db_path: join(homedir(), "Library/Application Support/Google/Chrome/Profile 1/Cookies"),
51
+ account: "Chrome",
52
+ service: "Chrome Safe Storage",
53
+ },
54
+ {
55
+ db_path: join(
56
+ homedir(),
57
+ "Library/Application Support/BraveSoftware/Brave-Browser/Default/Cookies",
58
+ ),
59
+ account: "Brave",
60
+ service: "Brave Safe Storage",
61
+ },
62
+ {
63
+ db_path: join(homedir(), "Library/Application Support/Microsoft Edge/Default/Cookies"),
64
+ account: "Microsoft Edge",
65
+ service: "Microsoft Edge Safe Storage",
66
+ },
67
+ ],
68
+ DEFAULT_MODEL_LI = [
69
+ {
70
+ id: "gemini-flash",
71
+ model_id: "56fdd199312815e2",
72
+ disp: "Flash",
73
+ cat: "Flash",
74
+ desc: "Default Flash",
75
+ num: 1,
76
+ capacity: 1,
77
+ alias_li: ["gemini-flash", "flash", "default"],
78
+ },
79
+ {
80
+ id: "gemini-pro",
81
+ model_id: "797f3d0293f288ad",
82
+ disp: "Pro",
83
+ cat: "Pro",
84
+ desc: "Default Pro",
85
+ num: 3,
86
+ capacity: 1,
87
+ alias_li: ["gemini-pro", "pro"],
88
+ },
89
+ ];
@@ -0,0 +1,65 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { BROWSER_PATH_LI, IV, SALT } from "./constant.js";
5
+
6
+ export const keychainPwdRead = (account, service) => {
7
+ const proc = spawnSync(
8
+ "/usr/bin/security",
9
+ ["-q", "find-generic-password", "-w", "-a", account, "-s", service],
10
+ { encoding: "utf8" },
11
+ );
12
+ return (proc.stdout ?? "").trim();
13
+ },
14
+
15
+ valDecrypt = async (enc_data, aes_key, has_integrity) => {
16
+ const data = enc_data.slice(3),
17
+ dec = await crypto.subtle.decrypt({ name: "AES-CBC", iv: IV }, aes_key, data);
18
+ let byte_li = new Uint8Array(dec);
19
+ if (has_integrity) byte_li = byte_li.slice(32);
20
+ return new TextDecoder().decode(byte_li);
21
+ },
22
+
23
+ cookieRead = async () => {
24
+ if (process.env.SECURE_1PSID && process.env.SECURE_1PSIDTS) {
25
+ return (
26
+ "__Secure-1PSID=" +
27
+ process.env.SECURE_1PSID +
28
+ "; __Secure-1PSIDTS=" +
29
+ process.env.SECURE_1PSIDTS
30
+ );
31
+ }
32
+ const target = BROWSER_PATH_LI.find((browser_cfg) => existsSync(browser_cfg.db_path));
33
+ if (!target) return "";
34
+ const pwd = keychainPwdRead(target.account, target.service),
35
+ key_mat = await crypto.subtle.importKey("raw", new TextEncoder().encode(pwd), "PBKDF2", false, [
36
+ "deriveKey",
37
+ ]),
38
+ aes_key = await crypto.subtle.deriveKey(
39
+ { name: "PBKDF2", salt: SALT, iterations: 1003, hash: "SHA-1" },
40
+ key_mat,
41
+ { name: "AES-CBC", length: 128 },
42
+ false,
43
+ ["decrypt"],
44
+ ),
45
+ db = new DatabaseSync(target.db_path, { readOnly: true }),
46
+ version_row = db.prepare("SELECT value FROM meta WHERE key = 'version'").get(),
47
+ has_integrity = parseInt(version_row?.value ?? "0", 10) >= 24,
48
+ row_li = db
49
+ .prepare(
50
+ "SELECT name, encrypted_value FROM cookies WHERE host_key LIKE '%google.com%' AND name IN ('__Secure-1PSID', '__Secure-1PSIDTS')",
51
+ )
52
+ .all(),
53
+ cookie_map = {};
54
+
55
+ for (const { name, encrypted_value } of row_li) {
56
+ if (encrypted_value && encrypted_value.length > 3) {
57
+ const val = await valDecrypt(encrypted_value, aes_key, has_integrity);
58
+ cookie_map[name] = val;
59
+ }
60
+ }
61
+ db.close();
62
+ return Object.entries(cookie_map)
63
+ .map(([cookie_name, cookie_val]) => cookie_name + "=" + cookie_val)
64
+ .join("; ");
65
+ };
@@ -0,0 +1,278 @@
1
+ import { BATCH_URL, DEFAULT_MODEL_LI, USER_AGENT } from "./constant.js";
2
+ import { session_state } from "./sessionState.js";
3
+
4
+ export const versionCompare = (a_ver, b_ver) => {
5
+ const a_match = (a_ver ?? "").match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/),
6
+ b_match = (b_ver ?? "").match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/),
7
+ a_maj = a_match ? parseInt(a_match[1], 10) : 0,
8
+ a_min = a_match && a_match[2] ? parseInt(a_match[2], 10) : 0,
9
+ a_pat = a_match && a_match[3] ? parseInt(a_match[3], 10) : 0,
10
+ b_maj = b_match ? parseInt(b_match[1], 10) : 0,
11
+ b_min = b_match && b_match[2] ? parseInt(b_match[2], 10) : 0,
12
+ b_pat = b_match && b_match[3] ? parseInt(b_match[3], 10) : 0;
13
+ if (a_maj !== b_maj) return a_maj - b_maj;
14
+ if (a_min !== b_min) return a_min - b_min;
15
+ return a_pat - b_pat;
16
+ },
17
+
18
+ stringVisualWidth = (str) => {
19
+ let width = 0;
20
+ for (const ch of str ?? "") {
21
+ const code = ch.codePointAt(0);
22
+ if (
23
+ (code >= 0x1100 && code <= 0x115f) ||
24
+ (code >= 0x2e80 && code <= 0xa4cf) ||
25
+ (code >= 0xac00 && code <= 0xd7a3) ||
26
+ (code >= 0xf900 && code <= 0xfaff) ||
27
+ (code >= 0xfe10 && code <= 0xfe19) ||
28
+ (code >= 0xfe30 && code <= 0xfe6f) ||
29
+ (code >= 0xff00 && code <= 0xff60) ||
30
+ (code >= 0xffe0 && code <= 0xffe6)
31
+ ) {
32
+ width += 2;
33
+ } else {
34
+ width += 1;
35
+ }
36
+ }
37
+ return width;
38
+ },
39
+
40
+ stringPadEnd = (str, target_width) => {
41
+ const current_width = stringVisualWidth(str);
42
+ return str + " ".repeat(Math.max(0, target_width - current_width));
43
+ },
44
+
45
+ modelListFormat = (model_li = null, default_model = null) => {
46
+ const target_model_li =
47
+ model_li && model_li.length > 0
48
+ ? model_li
49
+ : session_state.model_li.length > 0
50
+ ? session_state.model_li
51
+ : DEFAULT_MODEL_LI,
52
+ target_default = default_model ?? session_state.default_model ?? target_model_li[0],
53
+ sorted_model_li = [...target_model_li].sort((a, b) => {
54
+ if (a.id === target_default?.id) return -1;
55
+ if (b.id === target_default?.id) return 1;
56
+ return 0;
57
+ }),
58
+ is_tty = Boolean(process.stdout?.isTTY),
59
+ color = {
60
+ reset: is_tty ? "\x1b[0m" : "",
61
+ bold: is_tty ? "\x1b[1m" : "",
62
+ dim: is_tty ? "\x1b[2m" : "",
63
+ cyan: is_tty ? "\x1b[36m" : "",
64
+ green: is_tty ? "\x1b[32m" : "",
65
+ yellow: is_tty ? "\x1b[33m" : "",
66
+ gray: is_tty ? "\x1b[90m" : "",
67
+ },
68
+ headers = ["模型 ID (Model ID)", "显示名称 (Name)", "别名 (Aliases)"],
69
+ raw_rows = sorted_model_li.map((item) => {
70
+ const is_def = item.id === target_default?.id,
71
+ clean_aliases = (item.alias_li ?? [])
72
+ .filter((a) => a && a !== item.id && !/^[0-9a-f]{16}$/i.test(a))
73
+ .filter((a, idx, arr) => arr.indexOf(a) === idx)
74
+ .slice(0, 5)
75
+ .join(", ");
76
+ return [
77
+ (is_def ? "★ " : " ") + item.id + (is_def ? " (默认)" : ""),
78
+ item.disp ?? item.id,
79
+ clean_aliases || "-",
80
+ ];
81
+ }),
82
+ col_widths = headers.map((h, i) =>
83
+ Math.max(stringVisualWidth(h), ...raw_rows.map((r) => stringVisualWidth(r[i]))),
84
+ ),
85
+ border_color = color.gray,
86
+ top_border =
87
+ border_color +
88
+ "┌─" +
89
+ col_widths.map((w) => "─".repeat(w)).join("─┬─") +
90
+ "─┐" +
91
+ color.reset,
92
+ mid_border =
93
+ border_color +
94
+ "├─" +
95
+ col_widths.map((w) => "─".repeat(w)).join("─┼─") +
96
+ "─┤" +
97
+ color.reset,
98
+ bot_border =
99
+ border_color +
100
+ "└─" +
101
+ col_widths.map((w) => "─".repeat(w)).join("─┴─") +
102
+ "─┘" +
103
+ color.reset,
104
+ header_line =
105
+ border_color +
106
+ "│ " +
107
+ headers
108
+ .map((h, i) => color.bold + color.cyan + stringPadEnd(h, col_widths[i]) + color.reset)
109
+ .join(border_color + " │ ") +
110
+ border_color +
111
+ " │" +
112
+ color.reset,
113
+ row_lines = raw_rows.map((r, idx) => {
114
+ const item = sorted_model_li[idx],
115
+ is_def = item.id === target_default?.id,
116
+ c0_pad = stringPadEnd(r[0], col_widths[0]),
117
+ c1_pad = stringPadEnd(r[1], col_widths[1]),
118
+ c2_pad = stringPadEnd(r[2], col_widths[2]),
119
+ c0 = is_def
120
+ ? color.green + color.bold + c0_pad + color.reset
121
+ : color.yellow + c0_pad + color.reset,
122
+ c1 = color.bold + c1_pad + color.reset,
123
+ c2 = color.dim + c2_pad + color.reset;
124
+ return (
125
+ border_color +
126
+ "│ " +
127
+ c0 +
128
+ border_color +
129
+ " │ " +
130
+ c1 +
131
+ border_color +
132
+ " │ " +
133
+ c2 +
134
+ border_color +
135
+ " │" +
136
+ color.reset
137
+ );
138
+ }),
139
+ output_parts = [
140
+ color.bold + color.cyan + "支持的模型列表 (Supported Models):" + color.reset,
141
+ top_border,
142
+ header_line,
143
+ mid_border,
144
+ ...row_lines,
145
+ bot_border,
146
+ color.dim + " ★ = 默认模型 | 支持在请求中传入模型 ID 或任意别名" + color.reset,
147
+ ];
148
+ return output_parts.join("\n");
149
+ },
150
+
151
+ modelListPrint = (model_li = null, default_model = null) => {
152
+ console.log(modelListFormat(model_li, default_model));
153
+ },
154
+
155
+ modelFetch = async (at, bl, fsid, cookie_header) => {
156
+ ++session_state.req_id;
157
+ const session_id = crypto.randomUUID().toUpperCase(),
158
+ batch_headers = {
159
+ "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
160
+ Origin: "https://gemini.google.com",
161
+ Referer: "https://gemini.google.com/",
162
+ "X-Same-Domain": "1",
163
+ "User-Agent": USER_AGENT,
164
+ Cookie: cookie_header,
165
+ "x-goog-ext-525001261-jspb": JSON.stringify([
166
+ 1,
167
+ null,
168
+ null,
169
+ null,
170
+ null,
171
+ null,
172
+ null,
173
+ null,
174
+ [4, 5, 6, 8],
175
+ null,
176
+ null,
177
+ null,
178
+ null,
179
+ null,
180
+ null,
181
+ null,
182
+ session_id,
183
+ ]),
184
+ "x-goog-ext-73010989-jspb": "[0]",
185
+ },
186
+ payload = [[["otAQ7b", "[]", null, "generic"]]],
187
+ form_data = new URLSearchParams(),
188
+ batch_url = new URL(BATCH_URL),
189
+ discovered_li = [];
190
+
191
+ form_data.set("at", at);
192
+ form_data.set("f.req", JSON.stringify(payload));
193
+
194
+ batch_url.searchParams.set("rpcids", "otAQ7b");
195
+ batch_url.searchParams.set("hl", "en");
196
+ batch_url.searchParams.set("_reqid", String(session_state.req_id));
197
+ batch_url.searchParams.set("rt", "c");
198
+ batch_url.searchParams.set("source-path", "/app");
199
+ if (bl) batch_url.searchParams.set("bl", bl);
200
+ if (fsid) batch_url.searchParams.set("f.sid", fsid);
201
+
202
+ const res = await fetch(batch_url.toString(), {
203
+ method: "POST",
204
+ headers: batch_headers,
205
+ body: form_data.toString(),
206
+ });
207
+
208
+ const res_text = await res.text();
209
+ let clean_text = res_text;
210
+ if (clean_text.startsWith(")]}\x27")) clean_text = clean_text.slice(4).trimStart();
211
+ const match_res = clean_text.match(/^(\d+)\n/);
212
+ if (match_res) {
213
+ const chunk_len = parseInt(match_res[1], 10),
214
+ start_idx = match_res[1].length,
215
+ chunk_str = clean_text.slice(start_idx, start_idx + chunk_len).trim();
216
+ if (chunk_str.startsWith("[")) {
217
+ const part_li = JSON.parse(chunk_str);
218
+ part_li.forEach((part) => {
219
+ if (part[1] === "otAQ7b" && part[2]) {
220
+ const part_body = JSON.parse(part[2]),
221
+ model_li = part_body[15],
222
+ tier_flag_li = part_body[16] ?? [],
223
+ capability_flag_li = part_body[17] ?? [];
224
+ let cap = 1;
225
+ if (capability_flag_li.includes(115)) cap = 4;
226
+ else if (tier_flag_li.includes(16) || capability_flag_li.includes(106)) cap = 3;
227
+ else if (tier_flag_li.includes(8) || capability_flag_li.includes(19)) cap = 2;
228
+
229
+ (model_li ?? []).forEach((item) => {
230
+ const id = item[0],
231
+ cat = String(item[1] ?? item[10] ?? ""),
232
+ disp = String(item[11] ?? item[19] ?? item[1] ?? ""),
233
+ desc = String(item[12] ?? item[2] ?? ""),
234
+ num =
235
+ typeof item[17] === "number" ? item[17] : typeof item[9] === "number" ? item[9] : 1,
236
+ disp_slug = disp.toLowerCase().replaceAll(/\s+/g, "-"),
237
+ cat_slug = cat.toLowerCase().replaceAll(/\s+/g, "-"),
238
+ primary_id = "gemini-" + disp_slug,
239
+ alias_li = [id.toLowerCase(), primary_id, "gemini-" + cat_slug, cat_slug, disp_slug];
240
+ discovered_li.push({
241
+ id: primary_id,
242
+ model_id: id,
243
+ disp,
244
+ cat,
245
+ desc,
246
+ num,
247
+ capacity: cap,
248
+ alias_li,
249
+ });
250
+ });
251
+ }
252
+ });
253
+ }
254
+ }
255
+
256
+ const non_lite_li = discovered_li.filter(
257
+ (model_item) =>
258
+ !model_item.disp.toLowerCase().includes("lite") &&
259
+ !model_item.cat.toLowerCase().includes("lite") &&
260
+ !model_item.id.toLowerCase().includes("lite"),
261
+ );
262
+ non_lite_li.sort((a, b) => versionCompare(b.disp, a.disp));
263
+ session_state.default_model = non_lite_li[0] ?? discovered_li[0] ?? DEFAULT_MODEL_LI[0];
264
+
265
+ return discovered_li;
266
+ },
267
+
268
+ modelMap = (req_model) => {
269
+ const norm = (req_model ?? "").toLowerCase(),
270
+ available_li = session_state.model_li.length > 0 ? session_state.model_li : DEFAULT_MODEL_LI,
271
+ found = available_li.find(
272
+ (model_item) =>
273
+ model_item.id === norm ||
274
+ model_item.model_id === norm ||
275
+ model_item.alias_li.some((alias_item) => norm.includes(alias_item) || alias_item === norm),
276
+ );
277
+ return found ?? session_state.default_model ?? available_li[0];
278
+ };
@@ -0,0 +1,115 @@
1
+ import {
2
+ ENABLE_THINKING,
3
+ THINKING_LEVEL_DISABLED,
4
+ THINKING_LEVEL_ENABLED,
5
+ } from "./constant.js";
6
+ import {
7
+ toolPromptBuild,
8
+ toolResultFormat,
9
+ toolTailAnchorBuild,
10
+ } from "./toolHandle.js";
11
+
12
+ export const conversationFormat = (msg_li, tool_li = null, tool_choice = null) => {
13
+ const parts_li = [],
14
+ tools_prompt = toolPromptBuild(tool_li, tool_choice);
15
+
16
+ if (tools_prompt) {
17
+ parts_li.push("[System instruction]: " + tools_prompt);
18
+ }
19
+
20
+ (msg_li ?? []).forEach((msg) => {
21
+ const { role, content, name, toolName, tool_name, toolCallId, tool_call_id } = msg,
22
+ raw_calls = msg.tool_calls ?? msg.toolCalls,
23
+ tool_calls = Array.isArray(raw_calls) ? raw_calls : null,
24
+ text_content = Array.isArray(content)
25
+ ? content
26
+ .filter((item) => item.type === "text" || item.type === "input_text")
27
+ .map((item) => item.text)
28
+ .join("")
29
+ : content ?? "";
30
+
31
+ if (role === "system") {
32
+ parts_li.push("System: " + text_content);
33
+ } else if (role === "user") {
34
+ parts_li.push("Human: " + text_content);
35
+ } else if (role === "assistant") {
36
+ if (tool_calls && tool_calls.length > 0) {
37
+ const tc_str_li = tool_calls.map((tc) => {
38
+ const fn = tc.function ?? tc,
39
+ fn_name = fn.name ?? tc.name ?? "",
40
+ raw_args = fn.arguments ?? tc.arguments ?? tc.input ?? {};
41
+ let parsed_args = {};
42
+ try {
43
+ parsed_args = typeof raw_args === "string" ? JSON.parse(raw_args) : raw_args;
44
+ } catch {
45
+ parsed_args = {};
46
+ }
47
+ return (
48
+ "```tool_call\n" +
49
+ JSON.stringify({ name: fn_name, arguments: parsed_args }) +
50
+ "\n```"
51
+ );
52
+ });
53
+ const prefix = text_content ? "Assistant: " + text_content + "\n" : "Assistant:\n";
54
+ parts_li.push(prefix + tc_str_li.join("\n"));
55
+ } else {
56
+ parts_li.push("Assistant: " + text_content);
57
+ }
58
+ } else if (role === "tool") {
59
+ const tool_label = name ?? toolName ?? tool_name ?? toolCallId ?? tool_call_id ?? "";
60
+ parts_li.push(toolResultFormat(tool_label, text_content));
61
+ }
62
+ });
63
+
64
+ if (tools_prompt) {
65
+ parts_li.push(toolTailAnchorBuild());
66
+ }
67
+
68
+ return parts_li.join("\n\n").trim();
69
+ },
70
+
71
+ payloadBuild = (prompt, model_info) => {
72
+ const session_id = crypto.randomUUID().toUpperCase(),
73
+ uuid_val = crypto.randomUUID().toUpperCase(),
74
+ thinking_level = ENABLE_THINKING ? THINKING_LEVEL_ENABLED : THINKING_LEVEL_DISABLED,
75
+ model_header = [
76
+ 1,
77
+ null,
78
+ null,
79
+ null,
80
+ model_info.model_id,
81
+ null,
82
+ null,
83
+ 0,
84
+ [4, 5, 6, 8],
85
+ null,
86
+ null,
87
+ model_info.capacity ?? 1,
88
+ null,
89
+ null,
90
+ model_info.num,
91
+ thinking_level,
92
+ session_id,
93
+ ],
94
+ inner_req = Array.from({ length: 81 }, () => null);
95
+
96
+ inner_req[0] = [prompt, 0, null, null, null, null, 0];
97
+ inner_req[1] = ["en"];
98
+ inner_req[2] = ["", "", "", null, null, null, null, null, null, ""];
99
+ inner_req[6] = [1];
100
+ inner_req[7] = 1;
101
+ inner_req[10] = 1;
102
+ inner_req[11] = 0;
103
+ inner_req[17] = [[0]];
104
+ inner_req[18] = 0;
105
+ inner_req[27] = 1;
106
+ inner_req[30] = [4];
107
+ inner_req[41] = [1];
108
+ inner_req[53] = 0;
109
+ inner_req[59] = uuid_val;
110
+ inner_req[61] = [];
111
+ inner_req[68] = 1;
112
+ inner_req[79] = model_info.num;
113
+ inner_req[80] = thinking_level;
114
+ return [inner_req, model_header, uuid_val];
115
+ };