qwen-api-proxy 1.0.12 → 1.0.14

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.
@@ -14,7 +14,7 @@ const DOCUMENT_FILE_TYPE = 'document';
14
14
 
15
15
  function validateBrowserContext() {
16
16
  const browserContext = getBrowserContext();
17
- if (!browserContext) throw new Error('Браузер не инициализирован');
17
+ if (!browserContext) {throw new Error('Браузер не инициализирован');}
18
18
  return browserContext;
19
19
  }
20
20
 
@@ -29,7 +29,7 @@ async function validateAuthToken(browserContext) {
29
29
  if (!token) {
30
30
  logInfo('Токен авторизации не найден в памяти, пытаемся извлечь из браузера');
31
31
  token = await extractAuthToken(browserContext);
32
- if (!token) throw new Error('Не удалось получить токен авторизации');
32
+ if (!token) {throw new Error('Не удалось получить токен авторизации');}
33
33
  }
34
34
  return token;
35
35
  }
@@ -49,7 +49,7 @@ export async function getStsToken(fileInfo) {
49
49
  headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${data.token}`, 'Accept': 'application/json' },
50
50
  body: JSON.stringify(data.fileInfo)
51
51
  });
52
- if (response.ok) return { success: true, data: await response.json() };
52
+ if (response.ok) {return { success: true, data: await response.json() };}
53
53
  return { success: false, status: response.status, statusText: response.statusText, errorBody: await response.text() };
54
54
  } catch (error) { return { success: false, error: error.toString() }; }
55
55
  }, { apiUrl: STS_TOKEN_API_URL, token, fileInfo });
@@ -78,9 +78,9 @@ export async function uploadFile(filePath, stsData) {
78
78
  throw new Error('Некорректные или неполные данные STS токена');
79
79
  }
80
80
 
81
- logInfo(`[OSS] Загрузка через браузер`);
81
+ logInfo('[OSS] Загрузка через браузер');
82
82
  logInfo(`[OSS] Регион: ${stsData.region}, Бакет: ${stsData.bucketname}`);
83
- if (stsData.endpoint) logInfo(`[OSS] Endpoint: ${stsData.endpoint}`);
83
+ if (stsData.endpoint) {logInfo(`[OSS] Endpoint: ${stsData.endpoint}`);}
84
84
  logInfo(`[OSS] File path: ${stsData.file_path}`);
85
85
  logInfo(`[OSS] File URL: ${stsData.file_url}`);
86
86
 
@@ -104,11 +104,11 @@ export async function uploadFile(filePath, stsData) {
104
104
  });
105
105
  console.log('[OSS] SDK загружен успешно');
106
106
  }
107
-
107
+
108
108
  console.log('[OSS] Создание Blob из файла...');
109
- const blob = new Blob([Uint8Array.from(atob(data.fileBase64), c => c.charCodeAt(0))]);
109
+ const blob = new Blob([Uint8Array.from(atob(data.fileBase64), (c) => c.charCodeAt(0))]);
110
110
  console.log(`[OSS] Blob создан, размер: ${blob.size} байт`);
111
-
111
+
112
112
  console.log('[OSS] Создание OSS клиента...');
113
113
  const client = new window.OSS({
114
114
  region: data.stsData.region,
@@ -118,16 +118,16 @@ export async function uploadFile(filePath, stsData) {
118
118
  bucket: data.stsData.bucketname,
119
119
  secure: true
120
120
  });
121
-
121
+
122
122
  console.log(`[OSS] Загрузка файла в OSS: ${data.stsData.file_path}`);
123
123
  await client.put(data.stsData.file_path, blob);
124
124
  console.log('[OSS] Файл успешно загружен');
125
-
125
+
126
126
  return { success: true };
127
- } catch (error) {
127
+ } catch (error) {
128
128
  console.error(`[OSS Browser] Ошибка: ${error.toString()}`);
129
129
  console.error(`[OSS Browser] Stack: ${error.stack || 'N/A'}`);
130
- return { success: false, error: error.toString() };
130
+ return { success: false, error: error.toString() };
131
131
  }
132
132
  }, {
133
133
  fileBase64,
@@ -136,7 +136,7 @@ export async function uploadFile(filePath, stsData) {
136
136
  });
137
137
 
138
138
  if (result.success) {
139
- logInfo(`[OSS] Загрузка завершена успешно`);
139
+ logInfo('[OSS] Загрузка завершена успешно');
140
140
  return { success: true, fileName: path.basename(filePath), url: stsData.file_url, fileId: stsData.file_id, filePath: stsData.file_path };
141
141
  }
142
142
  logError(`[OSS] Ошибка загрузки: ${result.error}`);
@@ -151,27 +151,27 @@ export async function uploadFile(filePath, stsData) {
151
151
 
152
152
  export async function uploadFileToQwen(filePath) {
153
153
  try {
154
- if (!fs.existsSync(filePath)) throw new Error(`Файл не найден: ${filePath}`);
154
+ if (!fs.existsSync(filePath)) {throw new Error(`Файл не найден: ${filePath}`);}
155
155
 
156
156
  const fileName = path.basename(filePath);
157
157
  const fileSize = fs.statSync(filePath).size;
158
158
  const fileExt = path.extname(fileName).toLowerCase();
159
159
 
160
160
  let fileType = DEFAULT_FILE_TYPE;
161
- if (IMAGE_EXTENSIONS.includes(fileExt)) fileType = IMAGE_FILE_TYPE;
162
- else if (DOCUMENT_EXTENSIONS.includes(fileExt)) fileType = DOCUMENT_FILE_TYPE;
161
+ if (IMAGE_EXTENSIONS.includes(fileExt)) {fileType = IMAGE_FILE_TYPE;}
162
+ else if (DOCUMENT_EXTENSIONS.includes(fileExt)) {fileType = DOCUMENT_FILE_TYPE;}
163
163
 
164
164
  logInfo(`📤 Загрузка файла в Qwen: ${fileName} (${fileSize} байт, тип: ${fileType})`);
165
-
165
+
166
166
  const fileInfo = { filename: fileName, filesize: fileSize, filetype: fileType };
167
167
  const stsData = await getStsToken(fileInfo);
168
-
169
- logInfo(`✅ STS токен получен, начинаем загрузку в OSS`);
170
-
168
+
169
+ logInfo('✅ STS токен получен, начинаем загрузку в OSS');
170
+
171
171
  const uploadResult = await uploadFile(filePath, stsData);
172
-
173
- logInfo(`✅ Файл успешно загружен в Qwen`);
174
-
172
+
173
+ logInfo('✅ Файл успешно загружен в Qwen');
174
+
175
175
  return { ...uploadResult, fileInfo, stsData };
176
176
  } catch (error) {
177
177
  logError(`❌ Ошибка в процессе загрузки файла: ${error.message}`, error);
@@ -1,6 +1,6 @@
1
1
  // imageGeneration.js - Модуль для генерации изображений через Qwen Image API
2
2
  import axios from 'axios';
3
- import { logInfo, logError, logDebug } from '../logger/index.js';
3
+ import { logInfo, logError, logDebug, logWarn } from '../logger/index.js';
4
4
  import { sendMessage } from './chat.js';
5
5
  import { uploadFileToQwen } from './fileUpload.js';
6
6
  import { IMAGE_GENERATION_MODE, DASHSCOPE_API_KEY } from '../config.js';
@@ -27,7 +27,7 @@ const IMAGE_GENERATION_MODELS = [
27
27
  export async function generateImage(prompt, model = 'qwen-image-plus', options = {}) {
28
28
  // Определяем режим генерации
29
29
  const mode = IMAGE_GENERATION_MODE;
30
-
30
+
31
31
  if (mode === 'browser') {
32
32
  logInfo('🎨 Генерация изображения через browser mode...');
33
33
  return generateImageViaBrowser(prompt, model, options);
@@ -42,7 +42,7 @@ export async function generateImage(prompt, model = 'qwen-image-plus', options =
42
42
  */
43
43
  async function generateImageViaDashScope(prompt, model = 'qwen-image-plus', options = {}) {
44
44
  const apiKey = process.env.DASHSCOPE_API_KEY;
45
-
45
+
46
46
  if (!apiKey) {
47
47
  logError('API ключ DASHSCOPE_API_KEY не установлен');
48
48
  return {
@@ -71,17 +71,17 @@ async function generateImageViaDashScope(prompt, model = 'qwen-image-plus', opti
71
71
  // Если есть изображение для image-to-image
72
72
  if (options.imagePath) {
73
73
  logInfo(`📸 Image-to-image mode: загружаем файл ${options.imagePath}`);
74
-
74
+
75
75
  // Загружаем файл в Qwen и получаем URL
76
76
  const uploadResult = await uploadFileToQwen(options.imagePath);
77
-
77
+
78
78
  // Проверяем успешность загрузки
79
79
  if (!uploadResult || uploadResult.success === false) {
80
80
  const errorMsg = uploadResult?.error || 'Unknown error';
81
81
  logError(`❌ Ошибка загрузки файла: ${errorMsg}`);
82
82
  throw new Error(`Не удалось загрузить изображение: ${errorMsg}`);
83
83
  }
84
-
84
+
85
85
  if (uploadResult.file_url || uploadResult.url) {
86
86
  const fileUrl = uploadResult.file_url || uploadResult.url;
87
87
  logInfo(`✅ Файл загружен: ${fileUrl}`);
@@ -94,7 +94,7 @@ async function generateImageViaDashScope(prompt, model = 'qwen-image-plus', opti
94
94
 
95
95
  // Асинхронный запрос для Wan моделей
96
96
  const isWanModel = model.startsWith('wan');
97
- const endpoint = isWanModel
97
+ const endpoint = isWanModel
98
98
  ? `${DASHSCOPE_API_BASE}/services/aigc/text2image/image-synthesis`
99
99
  : `${DASHSCOPE_API_BASE}/services/aigc/text2image/image-synthesis`;
100
100
 
@@ -154,17 +154,17 @@ async function generateImageViaBrowser(prompt, model = 'qwen-image-plus', option
154
154
  let files = null;
155
155
  if (options.imagePath) {
156
156
  logInfo(`📸 Image-to-image mode: загружаем файл ${options.imagePath}`);
157
-
157
+
158
158
  // Загружаем файл в Qwen и получаем URL
159
159
  const uploadResult = await uploadFileToQwen(options.imagePath);
160
-
160
+
161
161
  // Проверяем успешность загрузки
162
162
  if (!uploadResult || uploadResult.success === false) {
163
163
  const errorMsg = uploadResult?.error || 'Unknown error';
164
164
  logError(`❌ Ошибка загрузки файла: ${errorMsg}`);
165
165
  throw new Error(`Не удалось загрузить изображение: ${errorMsg}`);
166
166
  }
167
-
167
+
168
168
  if (uploadResult.file_url || uploadResult.url) {
169
169
  const fileUrl = uploadResult.file_url || uploadResult.url;
170
170
  logInfo(`✅ Файл загружен: ${fileUrl}`);
@@ -202,7 +202,7 @@ async function generateImageViaBrowser(prompt, model = 'qwen-image-plus', option
202
202
 
203
203
  // Извлекаем URL изображения из ответа
204
204
  let imageUrl = null;
205
-
205
+
206
206
  // Проверяем разные форматы ответа
207
207
  if (result.imageUrl) {
208
208
  imageUrl = result.imageUrl;
@@ -232,15 +232,15 @@ async function generateImageViaBrowser(prompt, model = 'qwen-image-plus', option
232
232
  if (!imageUrl) {
233
233
  logError('❌ URL изображения не найден в ответе');
234
234
  logDebug('Response:', JSON.stringify(result, null, 2));
235
-
235
+
236
236
  // Логируем структуру ошибки для отладки
237
- if (result.error) logDebug('result.error exists:', JSON.stringify(result.error));
238
- if (result.errorBody) logDebug('result.errorBody exists:', result.errorBody.substring(0, 200));
239
- if (result.details) logDebug('result.details exists:', result.details.substring(0, 200));
240
-
237
+ if (result.error) {logDebug('result.error exists:', JSON.stringify(result.error));}
238
+ if (result.errorBody) {logDebug('result.errorBody exists:', result.errorBody.substring(0, 200));}
239
+ if (result.details) {logDebug('result.details exists:', result.details.substring(0, 200));}
240
+
241
241
  // Проверяем, есть ли в ответе реальная ошибка
242
242
  let errorMessage = 'Image URL not found in response';
243
-
243
+
244
244
  // Проверяем формат ошибки API (прямое поле error)
245
245
  if (result.error) {
246
246
  // API вернул ошибку
@@ -325,7 +325,7 @@ async function generateImageViaBrowser(prompt, model = 'qwen-image-plus', option
325
325
  // Не JSON, оставляем стандартное сообщение
326
326
  }
327
327
  }
328
-
328
+
329
329
  return {
330
330
  error: errorMessage,
331
331
  rawResponse: result
@@ -398,14 +398,14 @@ async function pollTaskStatus(taskId, apiKey) {
398
398
  }
399
399
 
400
400
  // PENDING или RUNNING - продолжаем опрос
401
- await new Promise(resolve => setTimeout(resolve, pollInterval));
401
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
402
402
 
403
403
  } catch (error) {
404
404
  logError(`Ошибка при опросе задачи ${taskId}`, error);
405
405
  if (attempt === maxAttempts - 1) {
406
406
  return { error: `Ошибка опроса: ${error.message}` };
407
407
  }
408
- await new Promise(resolve => setTimeout(resolve, pollInterval));
408
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
409
409
  }
410
410
  }
411
411
 
@@ -426,7 +426,7 @@ export function getAvailableImageModels() {
426
426
  */
427
427
  export async function checkImageApiAvailability() {
428
428
  const mode = IMAGE_GENERATION_MODE;
429
-
429
+
430
430
  // Browser mode всегда доступен (если браузер работает)
431
431
  if (mode === 'browser') {
432
432
  logDebug('🖼️ Browser mode: проверка через статус браузера');
@@ -435,10 +435,10 @@ export async function checkImageApiAvailability() {
435
435
  const isAuthenticated = getAuthenticationStatus();
436
436
  return !!(browserContext && isAuthenticated);
437
437
  }
438
-
438
+
439
439
  // DashScope mode: проверяем API ключ
440
440
  const apiKey = DASHSCOPE_API_KEY;
441
-
441
+
442
442
  if (!apiKey) {
443
443
  return false;
444
444
  }
@@ -9,182 +9,174 @@ const __dirname = path.dirname(__filename);
9
9
  const MODELS_FILE = path.join(__dirname, '..', 'AvailableModels.txt');
10
10
 
11
11
  const CANONICAL_MODELS = Object.freeze([
12
- "qwen3.5-plus",
13
- "qwen3.5-397b-a17b",
14
- "qwen3-max",
15
- "qwen3-vl-plus",
16
- "qwen3-coder-plus",
17
- "qwen3-omni-flash",
18
- "qwen3-omni-flash-2025-12-01",
19
- "qwen-max-latest",
20
- "qwen-plus-2025-09-11",
21
- "qwen-plus-2025-01-25",
22
- "qwq-32b",
23
- "qwen3-235b-a22b",
24
- "qwen3-30b-a3b",
25
- "qwen3-coder-30b-a3b-instruct",
26
- "qwen-turbo-2025-02-11",
27
- "qwen2.5-omni-7b",
28
- "qvq-72b-preview-0310",
29
- "qwen2.5-vl-32b-instruct",
30
- "qwen2.5-14b-instruct-1m",
31
- "qwen2.5-coder-32b-instruct",
32
- "qwen2.5-72b-instruct",
33
- "qwen3.5-plus",
34
- "qwen3.5-flash",
35
- "qwen3.5-397b-a17b",
36
- "qwen3.5-122b-a10b",
37
- "qwen3.5-27b",
38
- "qwen3.5-35b-a3b"
12
+ 'qwen3.5-plus',
13
+ 'qwen3.5-397b-a17b',
14
+ 'qwen3-max',
15
+ 'qwen3-vl-plus',
16
+ 'qwen3-coder-plus',
17
+ 'qwen3-omni-flash',
18
+ 'qwen3-omni-flash-2025-12-01',
19
+ 'qwen-max-latest',
20
+ 'qwen-plus-2025-09-11',
21
+ 'qwen-plus-2025-01-25',
22
+ 'qwq-32b',
23
+ 'qwen3-235b-a22b',
24
+ 'qwen3-30b-a3b',
25
+ 'qwen3-coder-30b-a3b-instruct',
26
+ 'qwen-turbo-2025-02-11',
27
+ 'qwen2.5-omni-7b',
28
+ 'qvq-72b-preview-0310',
29
+ 'qwen2.5-vl-32b-instruct',
30
+ 'qwen2.5-14b-instruct-1m',
31
+ 'qwen2.5-coder-32b-instruct',
32
+ 'qwen2.5-72b-instruct',
33
+ 'qwen3.5-plus',
34
+ 'qwen3.5-flash',
35
+ 'qwen3.5-397b-a17b',
36
+ 'qwen3.5-122b-a10b',
37
+ 'qwen3.5-27b',
38
+ 'qwen3.5-35b-a3b'
39
39
  ]);
40
40
 
41
41
  const CANONICAL_MODEL_SET = new Set(CANONICAL_MODELS);
42
42
 
43
43
  const ALIAS_GROUPS = Object.freeze({
44
- "qwen3.5-plus": [
45
- "qwen3.5",
46
- "Qwen3.5-Plus",
47
- "qwen3.5-plus-latest"
44
+ 'qwen3.5-plus': [
45
+ 'qwen3.5',
46
+ 'Qwen3.5-Plus',
47
+ 'qwen3.5-plus-latest'
48
48
  ],
49
- "qwen3.5-397b-a17b": [
50
- "qwen3.5-397b",
51
- "Qwen3.5-397B-A17B"
49
+ 'qwen3-max': [
50
+ 'qwen-max',
51
+ 'Qwen3-Max',
52
+ 'Qwen3-Maximum',
53
+ 'qwen3-max-preview',
54
+ 'Qwen3-Max-Preview'
52
55
  ],
53
- "qwen3-max": [
54
- "qwen-max",
55
- "Qwen3-Max",
56
- "Qwen3-Maximum",
57
- "qwen3-max-preview",
58
- "Qwen3-Max-Preview"
56
+ 'qwen3-vl-plus': [
57
+ 'qwen-vl',
58
+ 'qwen-vl-plus',
59
+ 'qwen-vl-plus-latest',
60
+ 'qwen-vl-max',
61
+ 'qwen-vl-max-latest',
62
+ 'Qwen3-VL-235B-A22B',
63
+ 'qwen3-vl-235b-a22b'
59
64
  ],
60
- "qwen3-vl-plus": [
61
- "qwen-vl",
62
- "qwen-vl-plus",
63
- "qwen-vl-plus-latest",
64
- "qwen-vl-max",
65
- "qwen-vl-max-latest",
66
- "Qwen3-VL-235B-A22B",
67
- "qwen3-vl-235b-a22b"
65
+ 'qwen3-coder-plus': [
66
+ 'qwen3-coder',
67
+ 'qwen-coder-plus',
68
+ 'qwen-coder-plus-latest',
69
+ 'Qwen3-Coder-Plus',
70
+ 'qwen2.5-coder-3b-instruct',
71
+ 'qwen2.5-coder-1.5b-instruct',
72
+ 'qwen2.5-coder-0.5b-instruct',
73
+ 'Qwen3-Coder'
68
74
  ],
69
- "qwen3-coder-plus": [
70
- "qwen3-coder",
71
- "qwen-coder-plus",
72
- "qwen-coder-plus-latest",
73
- "Qwen3-Coder-Plus",
74
- "qwen2.5-coder-3b-instruct",
75
- "qwen2.5-coder-1.5b-instruct",
76
- "qwen2.5-coder-0.5b-instruct",
77
- "Qwen3-Coder"
75
+ 'qwen3-omni-flash': [
76
+ 'qwen3-omni',
77
+ 'qwen3-omni-latest',
78
+ 'Qwen3-omni-flash',
79
+ 'Qwen3-Omni-Flash',
80
+ 'Qwen3-Omni'
78
81
  ],
79
- "qwen3-omni-flash": [
80
- "qwen3-omni",
81
- "qwen3-omni-latest",
82
- "Qwen3-omni-flash",
83
- "Qwen3-Omni-Flash",
84
- "Qwen3-Omni"
82
+ 'qwen3-omni-flash-2025-12-01': [
83
+ 'Qwen3-Omni-Flash-2025-12-01'
85
84
  ],
86
- "qwen3-omni-flash-2025-12-01": [
87
- "Qwen3-Omni-Flash-2025-12-01"
85
+ 'qwen-plus-2025-09-11': [
86
+ 'qwen-plus',
87
+ 'qwen-plus-latest',
88
+ 'Qwen3-Next',
89
+ 'Qwen3-Next-80B-A3B',
90
+ 'qwen3-next',
91
+ 'qwen3-next-80b-a3b'
88
92
  ],
89
- "qwen-plus-2025-09-11": [
90
- "qwen-plus",
91
- "qwen-plus-latest",
92
- "Qwen3-Next",
93
- "Qwen3-Next-80B-A3B",
94
- "qwen3-next",
95
- "qwen3-next-80b-a3b"
93
+ 'qwen3-235b-a22b': [
94
+ 'qwen3',
95
+ 'qwen-3',
96
+ 'qwen3-235b',
97
+ 'Qwen3-235B-A22B',
98
+ 'Qwen3-235B-A22B-2507',
99
+ 'qwen3-235b-a22b-2507'
96
100
  ],
97
- "qwen3-235b-a22b": [
98
- "qwen3",
99
- "qwen-3",
100
- "qwen3-235b",
101
- "Qwen3-235B-A22B",
102
- "Qwen3-235B-A22B-2507",
103
- "qwen3-235b-a22b-2507"
101
+ 'qwen3-30b-a3b': [
102
+ 'qwen3-plus',
103
+ 'qwen3-30b',
104
+ 'Qwen3-30B-A3B',
105
+ 'Qwen3-30B-A3B-2507',
106
+ 'qwen3-30b-a3b-2507'
104
107
  ],
105
- "qwen3-30b-a3b": [
106
- "qwen3-plus",
107
- "qwen3-30b",
108
- "Qwen3-30B-A3B",
109
- "Qwen3-30B-A3B-2507",
110
- "qwen3-30b-a3b-2507"
108
+ 'qwen3-coder-30b-a3b-instruct': [
109
+ 'qwen3-coder-flash',
110
+ 'Qwen3-Coder-Flash',
111
+ 'qwen3-coder-30b',
112
+ 'Qwen3-Coder-30B-A3B-Instruct'
111
113
  ],
112
- "qwen3-coder-30b-a3b-instruct": [
113
- "qwen3-coder-flash",
114
- "Qwen3-Coder-Flash",
115
- "qwen3-coder-30b",
116
- "Qwen3-Coder-30B-A3B-Instruct"
114
+ 'qwen-max-latest': [
115
+ 'Qwen2.5-Max',
116
+ 'qwen2.5-max'
117
117
  ],
118
- "qwen-max-latest": [
119
- "Qwen2.5-Max",
120
- "qwen2.5-max"
118
+ 'qwen-plus-2025-01-25': [
119
+ 'Qwen2.5-Plus',
120
+ 'qwen2.5-plus'
121
121
  ],
122
- "qwen-plus-2025-01-25": [
123
- "Qwen2.5-Plus",
124
- "qwen2.5-plus"
122
+ 'qwq-32b': [
123
+ 'qwq',
124
+ 'QwQ-32B',
125
+ 'qwq-32b-preview'
125
126
  ],
126
- "qwq-32b": [
127
- "qwq",
128
- "QwQ-32B",
129
- "qwq-32b-preview"
127
+ 'qwen-turbo-2025-02-11': [
128
+ 'qwen-turbo',
129
+ 'qwen-turbo-latest',
130
+ 'Qwen2.5-Turbo'
130
131
  ],
131
- "qwen-turbo-2025-02-11": [
132
- "qwen-turbo",
133
- "qwen-turbo-latest",
134
- "Qwen2.5-Turbo"
132
+ 'qwen2.5-omni-7b': [
133
+ 'qwen2.5-omni',
134
+ 'Qwen2.5-Omni-7B',
135
+ 'qwen-omni-7b'
135
136
  ],
136
- "qwen2.5-omni-7b": [
137
- "qwen2.5-omni",
138
- "Qwen2.5-Omni-7B",
139
- "qwen-omni-7b"
137
+ 'qvq-72b-preview-0310': [
138
+ 'qvq',
139
+ 'QVQ-Max',
140
+ 'qvq-72b'
140
141
  ],
141
- "qvq-72b-preview-0310": [
142
- "qvq",
143
- "QVQ-Max",
144
- "qvq-72b"
142
+ 'qwen2.5-vl-32b-instruct': [
143
+ 'qwen2.5-vl',
144
+ 'Qwen2.5-VL-32B-Instruct'
145
145
  ],
146
- "qwen2.5-vl-32b-instruct": [
147
- "qwen2.5-vl",
148
- "Qwen2.5-VL-32B-Instruct"
146
+ 'qwen2.5-14b-instruct-1m': [
147
+ 'qwen2.5-14b',
148
+ 'qwen2.5-coder-14b-instruct',
149
+ 'Qwen2.5-14B-Instruct-1M'
149
150
  ],
150
- "qwen2.5-14b-instruct-1m": [
151
- "qwen2.5-14b",
152
- "qwen2.5-coder-14b-instruct",
153
- "Qwen2.5-14B-Instruct-1M"
151
+ 'qwen2.5-coder-32b-instruct': [
152
+ 'qwen2.5-coder',
153
+ 'qwen2.5-coder-plus',
154
+ 'Qwen2.5-Coder-32B-Instruct'
154
155
  ],
155
- "qwen2.5-coder-32b-instruct": [
156
- "qwen2.5-coder",
157
- "qwen2.5-coder-plus",
158
- "Qwen2.5-Coder-32B-Instruct"
156
+ 'qwen2.5-72b-instruct': [
157
+ 'qwen2.5-72b',
158
+ 'Qwen2.5-72B-Instruct'
159
159
  ],
160
- "qwen2.5-72b-instruct": [
161
- "qwen2.5-72b",
162
- "Qwen2.5-72B-Instruct"
160
+ 'qwen3.5-flash': [
161
+ 'qwen3.5-flash-latest',
162
+ 'Qwen3.5-Flash'
163
163
  ],
164
- "qwen3.5-plus": [
165
- "qwen3.5-plus-latest",
166
- "Qwen3.5-Plus"
164
+ 'qwen3.5-397b-a17b': [
165
+ 'qwen3.5-397b',
166
+ 'Qwen3.5-397B-A17B',
167
+ 'qwen3.5-huge'
167
168
  ],
168
- "qwen3.5-flash": [
169
- "qwen3.5-flash-latest",
170
- "Qwen3.5-Flash"
169
+ 'qwen3.5-122b-a10b': [
170
+ 'qwen3.5-122b',
171
+ 'Qwen3.5-122B-A10B'
171
172
  ],
172
- "qwen3.5-397b-a17b": [
173
- "qwen3.5-397b",
174
- "Qwen3.5-397B-A17B",
175
- "qwen3.5-huge"
173
+ 'qwen3.5-27b': [
174
+ 'qwen3.5-27b-instruct',
175
+ 'Qwen3.5-27B'
176
176
  ],
177
- "qwen3.5-122b-a10b": [
178
- "qwen3.5-122b",
179
- "Qwen3.5-122B-A10B"
180
- ],
181
- "qwen3.5-27b": [
182
- "qwen3.5-27b-instruct",
183
- "Qwen3.5-27B"
184
- ],
185
- "qwen3.5-35b-a3b": [
186
- "qwen3.5-35b",
187
- "Qwen3.5-35B-A3B"
177
+ 'qwen3.5-35b-a3b': [
178
+ 'qwen3.5-35b',
179
+ 'Qwen3.5-35B-A3B'
188
180
  ]
189
181
  });
190
182
 
@@ -201,7 +193,7 @@ const buildModelMapping = () => {
201
193
  }
202
194
 
203
195
  for (const alias of aliases) {
204
- if (!alias) continue;
196
+ if (!alias) {continue;}
205
197
  mapping[alias] = target;
206
198
  }
207
199
  }
@@ -222,8 +214,8 @@ function getAvailableModelsList() {
222
214
  }
223
215
  return fs.readFileSync(MODELS_FILE, 'utf8')
224
216
  .split('\n')
225
- .map(l => l.trim())
226
- .filter(l => l && !l.startsWith('#'));
217
+ .map((l) => l.trim())
218
+ .filter((l) => l && !l.startsWith('#'));
227
219
  } catch (error) {
228
220
  return [];
229
221
  }
@@ -248,7 +240,7 @@ export function isValidModel(modelName) {
248
240
  export function getMappedModel(requestedModel, defaultModel = null) {
249
241
  // Если defaultModel не передан, используем динамический default
250
242
  const effectiveDefault = defaultModel || getActiveModel();
251
- if (!requestedModel) return effectiveDefault;
243
+ if (!requestedModel) {return effectiveDefault;}
252
244
 
253
245
  // Проверяем точное соответствие в словаре
254
246
  if (MODEL_MAPPING[requestedModel]) {
@@ -268,7 +260,7 @@ export function getMappedModel(requestedModel, defaultModel = null) {
268
260
  // Если запрошенная модель не найдена, логируем предупреждение
269
261
  logWarn(`Модель "${requestedModel}" не найдена в списке доступных.`);
270
262
  logWarn(`Используем модель по умолчанию: ${effectiveDefault}`);
271
-
263
+
272
264
  // Возвращаем модель по умолчанию
273
265
  return effectiveDefault;
274
- }
266
+ }