solver-sdk 1.8.1 → 1.9.0
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/dist/cjs/api/projects-api.js +4 -6
- package/dist/cjs/api/projects-api.js.map +1 -1
- package/dist/cjs/code-solver-sdk.js +13 -10
- package/dist/cjs/code-solver-sdk.js.map +1 -1
- package/dist/cjs/constants/websocket-events.constants.js +14 -1
- package/dist/cjs/constants/websocket-events.constants.js.map +1 -1
- package/dist/cjs/constants/websocket-namespaces.constants.js +18 -0
- package/dist/cjs/constants/websocket-namespaces.constants.js.map +1 -0
- package/dist/cjs/interfaces/websocket/callbacks.interfaces.js +3 -0
- package/dist/cjs/interfaces/websocket/callbacks.interfaces.js.map +1 -0
- package/dist/cjs/interfaces/websocket/client-options.interfaces.js +3 -0
- package/dist/cjs/interfaces/websocket/client-options.interfaces.js.map +1 -0
- package/dist/cjs/interfaces/websocket/events.interfaces.js +3 -0
- package/dist/cjs/interfaces/websocket/events.interfaces.js.map +1 -0
- package/dist/cjs/interfaces/websocket/stats.interfaces.js +3 -0
- package/dist/cjs/interfaces/websocket/stats.interfaces.js.map +1 -0
- package/dist/cjs/utils/code-solver-websocket-client.js +382 -1503
- package/dist/cjs/utils/code-solver-websocket-client.js.map +1 -1
- package/dist/cjs/utils/connection-state-manager.js +133 -0
- package/dist/cjs/utils/connection-state-manager.js.map +1 -0
- package/dist/cjs/utils/logger.js +106 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/cjs/utils/ping-pong-manager.js +306 -0
- package/dist/cjs/utils/ping-pong-manager.js.map +1 -0
- package/dist/cjs/utils/session-manager.js +114 -0
- package/dist/cjs/utils/session-manager.js.map +1 -0
- package/dist/cjs/ws/base-ws-client.js +286 -0
- package/dist/cjs/ws/base-ws-client.js.map +1 -0
- package/dist/cjs/ws/dependencies-ws-client.js +11 -0
- package/dist/cjs/ws/dependencies-ws-client.js.map +1 -0
- package/dist/cjs/ws/diagnostics-service.js +170 -0
- package/dist/cjs/ws/diagnostics-service.js.map +1 -0
- package/dist/cjs/ws/indexing-ws-client.js +223 -0
- package/dist/cjs/ws/indexing-ws-client.js.map +1 -0
- package/dist/cjs/ws/notifications-ws-client.js +12 -0
- package/dist/cjs/ws/notifications-ws-client.js.map +1 -0
- package/dist/cjs/ws/reasoning-ws-client.js +330 -0
- package/dist/cjs/ws/reasoning-ws-client.js.map +1 -0
- package/dist/esm/api/projects-api.js +4 -6
- package/dist/esm/api/projects-api.js.map +1 -1
- package/dist/esm/code-solver-sdk.js +6 -3
- package/dist/esm/code-solver-sdk.js.map +1 -1
- package/dist/esm/constants/websocket-events.constants.js +13 -0
- package/dist/esm/constants/websocket-events.constants.js.map +1 -1
- package/dist/esm/constants/websocket-namespaces.constants.js +15 -0
- package/dist/esm/constants/websocket-namespaces.constants.js.map +1 -0
- package/dist/esm/interfaces/websocket/callbacks.interfaces.js +2 -0
- package/dist/esm/interfaces/websocket/callbacks.interfaces.js.map +1 -0
- package/dist/esm/interfaces/websocket/client-options.interfaces.js +2 -0
- package/dist/esm/interfaces/websocket/client-options.interfaces.js.map +1 -0
- package/dist/esm/interfaces/websocket/events.interfaces.js +2 -0
- package/dist/esm/interfaces/websocket/events.interfaces.js.map +1 -0
- package/dist/esm/interfaces/websocket/stats.interfaces.js +2 -0
- package/dist/esm/interfaces/websocket/stats.interfaces.js.map +1 -0
- package/dist/esm/utils/code-solver-websocket-client.js +381 -1503
- package/dist/esm/utils/code-solver-websocket-client.js.map +1 -1
- package/dist/esm/utils/connection-state-manager.js +129 -0
- package/dist/esm/utils/connection-state-manager.js.map +1 -0
- package/dist/esm/utils/logger.js +101 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/ping-pong-manager.js +302 -0
- package/dist/esm/utils/ping-pong-manager.js.map +1 -0
- package/dist/esm/utils/session-manager.js +109 -0
- package/dist/esm/utils/session-manager.js.map +1 -0
- package/dist/esm/ws/base-ws-client.js +282 -0
- package/dist/esm/ws/base-ws-client.js.map +1 -0
- package/dist/esm/ws/dependencies-ws-client.js +7 -0
- package/dist/esm/ws/dependencies-ws-client.js.map +1 -0
- package/dist/esm/ws/diagnostics-service.js +166 -0
- package/dist/esm/ws/diagnostics-service.js.map +1 -0
- package/dist/esm/ws/indexing-ws-client.js +219 -0
- package/dist/esm/ws/indexing-ws-client.js.map +1 -0
- package/dist/esm/ws/notifications-ws-client.js +8 -0
- package/dist/esm/ws/notifications-ws-client.js.map +1 -0
- package/dist/esm/ws/reasoning-ws-client.js +326 -0
- package/dist/esm/ws/reasoning-ws-client.js.map +1 -0
- package/dist/types/api/projects-api.d.ts.map +1 -1
- package/dist/types/code-solver-sdk.d.ts +2 -1
- package/dist/types/code-solver-sdk.d.ts.map +1 -1
- package/dist/types/constants/websocket-events.constants.d.ts +12 -0
- package/dist/types/constants/websocket-events.constants.d.ts.map +1 -1
- package/dist/types/constants/websocket-namespaces.constants.d.ts +14 -0
- package/dist/types/constants/websocket-namespaces.constants.d.ts.map +1 -0
- package/dist/types/interfaces/websocket/callbacks.interfaces.d.ts +30 -0
- package/dist/types/interfaces/websocket/callbacks.interfaces.d.ts.map +1 -0
- package/dist/types/interfaces/websocket/client-options.interfaces.d.ts +51 -0
- package/dist/types/interfaces/websocket/client-options.interfaces.d.ts.map +1 -0
- package/dist/types/interfaces/websocket/events.interfaces.d.ts +165 -0
- package/dist/types/interfaces/websocket/events.interfaces.d.ts.map +1 -0
- package/dist/types/interfaces/websocket/stats.interfaces.d.ts +72 -0
- package/dist/types/interfaces/websocket/stats.interfaces.d.ts.map +1 -0
- package/dist/types/utils/code-solver-websocket-client.d.ts +70 -616
- package/dist/types/utils/code-solver-websocket-client.d.ts.map +1 -1
- package/dist/types/utils/connection-state-manager.d.ts +94 -0
- package/dist/types/utils/connection-state-manager.d.ts.map +1 -0
- package/dist/types/utils/logger.d.ts +62 -0
- package/dist/types/utils/logger.d.ts.map +1 -0
- package/dist/types/utils/ping-pong-manager.d.ts +118 -0
- package/dist/types/utils/ping-pong-manager.d.ts.map +1 -0
- package/dist/types/utils/session-manager.d.ts +98 -0
- package/dist/types/utils/session-manager.d.ts.map +1 -0
- package/dist/types/ws/base-ws-client.d.ts +119 -0
- package/dist/types/ws/base-ws-client.d.ts.map +1 -0
- package/dist/types/ws/dependencies-ws-client.d.ts +6 -0
- package/dist/types/ws/dependencies-ws-client.d.ts.map +1 -0
- package/dist/types/ws/diagnostics-service.d.ts +93 -0
- package/dist/types/ws/diagnostics-service.d.ts.map +1 -0
- package/dist/types/ws/indexing-ws-client.d.ts +78 -0
- package/dist/types/ws/indexing-ws-client.d.ts.map +1 -0
- package/dist/types/ws/notifications-ws-client.d.ts +5 -0
- package/dist/types/ws/notifications-ws-client.d.ts.map +1 -0
- package/dist/types/ws/reasoning-ws-client.d.ts +87 -0
- package/dist/types/ws/reasoning-ws-client.d.ts.map +1 -0
- package/docs/AUTHENTICATION.md +31 -127
- package/docs/WEBSOCKET.md +51 -211
- package/package.json +1 -1
|
@@ -1,1663 +1,542 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CodeSolverWebSocketClient = exports.WebSocketNamespace = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const websocket_events_constants_1 = require("../constants/websocket-events.constants");
|
|
5
|
+
const websocket_namespaces_constants_js_1 = require("../constants/websocket-namespaces.constants.js");
|
|
6
|
+
const logger_js_1 = require("./logger.js");
|
|
7
|
+
const base_ws_client_js_1 = require("../ws/base-ws-client.js");
|
|
8
|
+
// Реэкспортируем WebSocketNamespace для других модулей
|
|
9
|
+
var websocket_namespaces_constants_js_2 = require("../constants/websocket-namespaces.constants.js");
|
|
10
|
+
Object.defineProperty(exports, "WebSocketNamespace", { enumerable: true, get: function () { return websocket_namespaces_constants_js_2.WebSocketNamespace; } });
|
|
11
|
+
// Дополнительные события, которые могут отсутствовать в основном перечислении
|
|
12
|
+
const CUSTOM_EVENTS = {
|
|
13
|
+
GET_REASONING_STATUS: 'get_reasoning_status'
|
|
14
|
+
};
|
|
7
15
|
/**
|
|
8
|
-
*
|
|
16
|
+
* Специализированный WebSocket клиент для пространства имен reasoning
|
|
9
17
|
*/
|
|
10
|
-
|
|
11
|
-
(function (WebSocketNamespace) {
|
|
12
|
-
/** Основное пространство имен */
|
|
13
|
-
WebSocketNamespace["DEFAULT"] = "/";
|
|
14
|
-
/** Пространство для рассуждений */
|
|
15
|
-
WebSocketNamespace["REASONING"] = "/reasoning";
|
|
16
|
-
/** Пространство для индексации */
|
|
17
|
-
WebSocketNamespace["INDEXING"] = "/indexing";
|
|
18
|
-
/** Пространство для зависимостей */
|
|
19
|
-
WebSocketNamespace["DEPENDENCIES"] = "/dependencies";
|
|
20
|
-
})(WebSocketNamespace || (exports.WebSocketNamespace = WebSocketNamespace = {}));
|
|
21
|
-
/**
|
|
22
|
-
* WebSocket клиент для работы с Code Solver API
|
|
23
|
-
*/
|
|
24
|
-
class CodeSolverWebSocketClient {
|
|
18
|
+
class ReasoningWsClient extends base_ws_client_js_1.BaseWebSocketClient {
|
|
25
19
|
/**
|
|
26
|
-
* Создает новый WebSocket клиент для
|
|
20
|
+
* Создает новый WebSocket клиент для рассуждений
|
|
27
21
|
* @param {string} baseURL Базовый URL API
|
|
28
|
-
* @param {
|
|
22
|
+
* @param {BaseWebSocketClientOptions} options Опции клиента
|
|
29
23
|
*/
|
|
30
24
|
constructor(baseURL, options = {}) {
|
|
31
|
-
|
|
32
|
-
this.namespace = '';
|
|
33
|
-
/** WebSocket клиенты для разных пространств имен */
|
|
34
|
-
this.clients = new Map();
|
|
25
|
+
super(websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING, baseURL, options);
|
|
35
26
|
/** Активная сессия рассуждения */
|
|
36
27
|
this.activeReasoningId = null;
|
|
37
|
-
/** Активная сессия индексации */
|
|
38
|
-
this.activeProjectId = null;
|
|
39
|
-
/** Обработчики событий мышления */
|
|
40
|
-
this.thinkingEventHandlers = new Map();
|
|
41
|
-
/** Таймеры для ping/pong */
|
|
42
|
-
this.pingIntervals = new Map();
|
|
43
|
-
/** Статистика ping/pong */
|
|
44
|
-
this.pingStats = new Map();
|
|
45
|
-
/** Количество последовательных таймаутов */
|
|
46
|
-
this.pingTimeouts = new Map();
|
|
47
|
-
/** Задержка по умолчанию между ping-сообщениями (30 секунд) */
|
|
48
|
-
this.defaultPingInterval = 30000;
|
|
49
|
-
/** Порог таймаута (количество пропущенных pong) */
|
|
50
|
-
this.timeoutThreshold = 3;
|
|
51
|
-
/** Хранилище обработчиков ping/pong */
|
|
52
|
-
this.pingPongEventHandlers = new Map();
|
|
53
|
-
/** Токены сессий для разных пространств имен */
|
|
54
|
-
this.sessionTokens = new Map();
|
|
55
|
-
/** Состояние подключения для разных пространств имен */
|
|
56
|
-
this.connectionState = new Map();
|
|
57
|
-
/** Таймер для проверки здоровья соединений */
|
|
58
|
-
this.healthCheckTimer = null;
|
|
59
|
-
this.baseURL = baseURL.replace(/^http/, 'ws');
|
|
60
|
-
this.options = {
|
|
61
|
-
...options,
|
|
62
|
-
headers: {
|
|
63
|
-
...(options.headers || {}),
|
|
64
|
-
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {})
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
// Инициализируем пространство имен
|
|
68
|
-
this.namespace = String(WebSocketNamespace.REASONING);
|
|
69
28
|
}
|
|
70
29
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param {string}
|
|
73
|
-
* @param {
|
|
74
|
-
* @
|
|
30
|
+
* Подключается к серверу WebSocket с указанным ID рассуждения
|
|
31
|
+
* @param {string} reasoningId ID рассуждения
|
|
32
|
+
* @param {object} options Дополнительные опции
|
|
33
|
+
* @returns {Promise<boolean>} Успешность подключения
|
|
75
34
|
*/
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
else if (level === 'info') {
|
|
81
|
-
console.info(`[CodeSolverWebSocket] ${message}`, data);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
console.debug(`[CodeSolverWebSocket] ${message}`, data);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Подключается к пространству имен WebSocket
|
|
89
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
90
|
-
* @param {Record<string, any>} [params] Параметры подключения
|
|
91
|
-
* @returns {Promise<WebSocketClient>} WebSocket клиент
|
|
92
|
-
*/
|
|
93
|
-
async connect(namespace, params = {}) {
|
|
94
|
-
// Если клиент уже существует, возвращаем его
|
|
95
|
-
if (this.clients.has(namespace)) {
|
|
96
|
-
const client = this.clients.get(namespace);
|
|
97
|
-
// Если клиент уже подключен, возвращаем его
|
|
98
|
-
if (client.isConnected()) {
|
|
99
|
-
console.debug(`[WS] Уже подключен к ${namespace}`);
|
|
100
|
-
return client;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Формируем URL для подключения
|
|
104
|
-
let baseUrl;
|
|
105
|
-
let namespaceStr = '';
|
|
106
|
-
// Добавляем namespace в URL путь (стандартный подход Socket.IO)
|
|
107
|
-
if (namespace !== WebSocketNamespace.DEFAULT) {
|
|
108
|
-
namespaceStr = String(namespace);
|
|
109
|
-
if (!namespaceStr.startsWith('/')) {
|
|
110
|
-
namespaceStr = '/' + namespaceStr;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Формируем правильный URL для Socket.IO
|
|
114
|
-
if (this.baseURL.endsWith('/socket.io') || this.baseURL.endsWith('/socket.io/')) {
|
|
115
|
-
// Для случая когда URL заканчивается на /socket.io, убираем слеш
|
|
116
|
-
const cleanBaseUrl = this.baseURL.endsWith('/')
|
|
117
|
-
? this.baseURL.slice(0, -1)
|
|
118
|
-
: this.baseURL;
|
|
119
|
-
// Добавляем namespace к URL
|
|
120
|
-
baseUrl = cleanBaseUrl + namespaceStr;
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
// Для случая когда URL не содержит /socket.io
|
|
124
|
-
baseUrl = this.baseURL + namespaceStr;
|
|
35
|
+
async connectWithReasoning(reasoningId, options = {}) {
|
|
36
|
+
if (reasoningId) {
|
|
37
|
+
this.activeReasoningId = reasoningId;
|
|
125
38
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
url.searchParams.append('EIO', '4');
|
|
130
|
-
url.searchParams.append('transport', 'websocket');
|
|
131
|
-
// Добавляем параметры к URL
|
|
132
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
133
|
-
if (value !== undefined) {
|
|
134
|
-
url.searchParams.append(key, String(value));
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
const urlString = url.toString();
|
|
138
|
-
console.debug(`[WS] Подключение к ${urlString}`, {
|
|
139
|
-
namespace: String(namespace),
|
|
140
|
-
hasApiKey: !!this.options.apiKey,
|
|
141
|
-
apiKeyLength: this.options.apiKey ? this.options.apiKey.length : 0,
|
|
142
|
-
params: Object.keys(params)
|
|
143
|
-
});
|
|
144
|
-
// Создаем новый WebSocket клиент
|
|
145
|
-
const client = new websocket_client_js_1.WebSocketClient(urlString, {
|
|
146
|
-
...this.options,
|
|
147
|
-
namespace: namespaceStr
|
|
148
|
-
});
|
|
149
|
-
// Добавляем обработчик для успешного подключения и отправки аутентификации
|
|
150
|
-
client.on('open', () => {
|
|
151
|
-
console.debug(`[WS] Подключение к ${String(namespace)} установлено`, {
|
|
152
|
-
socketId: client.webSocket?.id,
|
|
153
|
-
readyState: client.webSocket?.readyState
|
|
154
|
-
});
|
|
155
|
-
// Отправляем сообщение аутентификации, если задан API ключ
|
|
156
|
-
if (this.options.apiKey && namespace !== WebSocketNamespace.DEFAULT) {
|
|
157
|
-
try {
|
|
158
|
-
const apiKeySafe = this.options.apiKey.length > 8
|
|
159
|
-
? `${this.options.apiKey.substring(0, 4)}...${this.options.apiKey.substring(this.options.apiKey.length - 4)}`
|
|
160
|
-
: '[короткий ключ]';
|
|
161
|
-
console.debug(`[WS] Отправка аутентификации для ${String(namespace)}`, {
|
|
162
|
-
namespace: String(namespace),
|
|
163
|
-
apiKey: apiKeySafe
|
|
164
|
-
});
|
|
165
|
-
// Отправляем сообщение аутентификации в формате Socket.IO
|
|
166
|
-
const authMessage = {
|
|
167
|
-
type: '2', // Socket.IO packet type: EVENT
|
|
168
|
-
nsp: String(namespace),
|
|
169
|
-
data: ['authenticate', { token: this.options.apiKey }]
|
|
170
|
-
};
|
|
171
|
-
client.send(authMessage);
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
console.error(`[WS] Ошибка при отправке аутентификации: ${error instanceof Error ? error.message : String(error)}`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
39
|
+
return super.connect({
|
|
40
|
+
reasoningId: this.activeReasoningId,
|
|
41
|
+
...options
|
|
177
42
|
});
|
|
178
|
-
// Логирование ошибок
|
|
179
|
-
client.on('error', (error) => {
|
|
180
|
-
console.error(`[WS] Ошибка соединения с ${namespace}: ${error instanceof Error ? error.message : String(error)}`);
|
|
181
|
-
});
|
|
182
|
-
// Логирование разъединений
|
|
183
|
-
client.on('close', (event) => {
|
|
184
|
-
console.debug(`[WS] Соединение с ${namespace} закрыто: ${event.code || 'нет кода'}, ${event.reason || 'Причина не указана'}`);
|
|
185
|
-
});
|
|
186
|
-
// Логирование сообщений для отладки
|
|
187
|
-
client.on('message', (data) => {
|
|
188
|
-
try {
|
|
189
|
-
console.debug(`[WS] Получено сообщение от ${namespace}: ${JSON.stringify(data).substring(0, 100)}...`);
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
console.debug(`[WS] Получено сообщение от ${namespace} (не может быть сериализовано в JSON)`);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
// Подключаемся к серверу
|
|
196
|
-
await client.connect();
|
|
197
|
-
// Сохраняем клиент
|
|
198
|
-
this.clients.set(namespace, client);
|
|
199
|
-
return client;
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Подключается к пространству имен индексации
|
|
203
|
-
* @param projectId ID проекта (опционально)
|
|
204
|
-
* @returns Promise с результатом подключения
|
|
205
|
-
*/
|
|
206
|
-
async connectToIndexing(withReconnection = true, createIfNotExistsOrFail = false, connTimeout = 6000) {
|
|
207
|
-
try {
|
|
208
|
-
this.logger('info', 'Подключение к пространству имен индексации', {
|
|
209
|
-
withReconnection,
|
|
210
|
-
createIfNotExistsOrFail,
|
|
211
|
-
connTimeout,
|
|
212
|
-
});
|
|
213
|
-
// Получаем параметры авторизации для пространства имен индексации
|
|
214
|
-
const sessionToken = this.getSessionToken(WebSocketNamespace.INDEXING);
|
|
215
|
-
const authParams = (0, reasoning_auth_helper_js_1.createIndexingConnectionParams)(this.options.apiKey, this.activeProjectId, sessionToken);
|
|
216
|
-
// Подключаемся к пространству имен индексации с параметрами аутентификации
|
|
217
|
-
const client = await this.connect(WebSocketNamespace.INDEXING, authParams);
|
|
218
|
-
// Аутентифицируемся с увеличенным таймаутом
|
|
219
|
-
try {
|
|
220
|
-
const authResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.AUTHENTICATE, {
|
|
221
|
-
token: this.options.apiKey,
|
|
222
|
-
projectId: this.activeProjectId
|
|
223
|
-
}, 10000);
|
|
224
|
-
this.logger('debug', 'Результат аутентификации в namespace индексации', authResult);
|
|
225
|
-
}
|
|
226
|
-
catch (error) {
|
|
227
|
-
this.logger('error', 'Ошибка аутентификации в namespace индексации', error);
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
// Если у нас есть ID проекта, присоединяемся к нему
|
|
231
|
-
if (this.activeProjectId) {
|
|
232
|
-
try {
|
|
233
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_PROJECT, {
|
|
234
|
-
projectId: this.activeProjectId,
|
|
235
|
-
token: this.options.apiKey
|
|
236
|
-
}, 10000);
|
|
237
|
-
this.logger('debug', 'Результат присоединения к проекту', joinResult);
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
catch (error) {
|
|
241
|
-
this.logger('error', 'Ошибка присоединения к проекту', error);
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
this.logger('error', 'Ошибка подключения к пространству имен индексации', error);
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
43
|
}
|
|
252
44
|
/**
|
|
253
|
-
*
|
|
254
|
-
* @
|
|
45
|
+
* Присоединяется к сессии рассуждения
|
|
46
|
+
* @param {string} reasoningId ID рассуждения
|
|
47
|
+
* @param {boolean} setActive Установить ли как активную сессию
|
|
48
|
+
* @returns {Promise<boolean>} Успешность операции
|
|
255
49
|
*/
|
|
256
|
-
async
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
await this.connect(WebSocketNamespace.DEFAULT);
|
|
260
|
-
return true;
|
|
261
|
-
}
|
|
262
|
-
catch (error) {
|
|
50
|
+
async joinReasoning(reasoningId, setActive = true) {
|
|
51
|
+
if (!this.isConnected()) {
|
|
52
|
+
this.logger.warn(`Попытка присоединения к рассуждению ${reasoningId}, но клиент не подключен`);
|
|
263
53
|
return false;
|
|
264
54
|
}
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Подключается к пространству имен dependencies
|
|
268
|
-
* @param projectId ID проекта (опционально)
|
|
269
|
-
* @returns Promise с результатом подключения
|
|
270
|
-
*/
|
|
271
|
-
async connectToDependencies(projectId) {
|
|
272
55
|
try {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
this.
|
|
277
|
-
}
|
|
278
|
-
// Подключаемся к пространству имен dependencies
|
|
279
|
-
const client = await this.connect(WebSocketNamespace.DEPENDENCIES);
|
|
280
|
-
// Аутентифицируемся с увеличенным таймаутом
|
|
281
|
-
try {
|
|
282
|
-
const authResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.AUTHENTICATE, {
|
|
283
|
-
token: this.options.apiKey,
|
|
284
|
-
projectId: this.activeProjectId
|
|
285
|
-
}, 10000);
|
|
286
|
-
this.logger('debug', 'Результат аутентификации в namespace dependencies', authResult);
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
this.logger('error', 'Ошибка аутентификации в namespace dependencies', error);
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
// Если у нас есть ID проекта, присоединяемся к нему
|
|
293
|
-
if (this.activeProjectId) {
|
|
294
|
-
try {
|
|
295
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_DEPENDENCIES, {
|
|
296
|
-
projectId: this.activeProjectId,
|
|
297
|
-
token: this.options.apiKey
|
|
298
|
-
}, 10000);
|
|
299
|
-
this.logger('debug', 'Результат присоединения к проекту', joinResult);
|
|
300
|
-
return true;
|
|
301
|
-
}
|
|
302
|
-
catch (error) {
|
|
303
|
-
this.logger('error', 'Ошибка присоединения к проекту', error);
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
56
|
+
// Отправляем запрос на присоединение
|
|
57
|
+
const result = await this.emitWithAck(websocket_events_constants_1.WebSocketEvents.JOIN_REASONING, { reasoningId });
|
|
58
|
+
if (result.success && setActive) {
|
|
59
|
+
this.activeReasoningId = reasoningId;
|
|
306
60
|
}
|
|
307
|
-
return
|
|
61
|
+
return result.success;
|
|
308
62
|
}
|
|
309
63
|
catch (error) {
|
|
310
|
-
this.logger(
|
|
64
|
+
this.logger.error(`Ошибка при присоединении к рассуждению ${reasoningId}`, error);
|
|
311
65
|
return false;
|
|
312
66
|
}
|
|
313
67
|
}
|
|
314
68
|
/**
|
|
315
|
-
*
|
|
316
|
-
* @param {
|
|
69
|
+
* Подключает к сессии рассуждения и устанавливает обработчик для thinking
|
|
70
|
+
* @param {string} reasoningId ID рассуждения
|
|
71
|
+
* @param {function} thinkingHandler Обработчик событий thinking
|
|
72
|
+
* @returns {Promise<string>} ID рассуждения
|
|
317
73
|
*/
|
|
318
|
-
|
|
319
|
-
//
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
client.close();
|
|
324
|
-
this.clients.delete(namespaceEnum);
|
|
74
|
+
async connectToThinkingSession(reasoningId, thinkingHandler) {
|
|
75
|
+
// Сначала подключаемся к сессии рассуждения
|
|
76
|
+
const connected = await this.connectWithReasoning(reasoningId, { autoJoin: true });
|
|
77
|
+
if (!connected) {
|
|
78
|
+
throw new Error(`Не удалось подключиться к рассуждению ${reasoningId}`);
|
|
325
79
|
}
|
|
326
|
-
//
|
|
327
|
-
if (
|
|
328
|
-
this.
|
|
329
|
-
}
|
|
330
|
-
else if (namespaceEnum === WebSocketNamespace.INDEXING) {
|
|
331
|
-
this.activeProjectId = null;
|
|
80
|
+
// Затем подписываемся на мышление, если указан обработчик
|
|
81
|
+
if (thinkingHandler) {
|
|
82
|
+
this.subscribeToThinking(thinkingHandler);
|
|
332
83
|
}
|
|
84
|
+
return reasoningId;
|
|
333
85
|
}
|
|
334
86
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
87
|
+
* Подписаться на события мышления
|
|
88
|
+
* @param callback Функция обратного вызова для обработки событий мышления
|
|
337
89
|
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
this.disablePingPong();
|
|
341
|
-
// Отключаемся от всех namespace
|
|
342
|
-
for (const [namespace, client] of this.clients.entries()) {
|
|
343
|
-
if (client) {
|
|
344
|
-
client.close();
|
|
345
|
-
this.clients.delete(namespace);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
// Сбрасываем активные сессии
|
|
349
|
-
this.activeReasoningId = null;
|
|
350
|
-
this.activeProjectId = null;
|
|
90
|
+
subscribeToThinking(callback) {
|
|
91
|
+
this.on(websocket_events_constants_1.ReasoningEventNames.THINKING, callback);
|
|
351
92
|
}
|
|
352
93
|
/**
|
|
353
|
-
*
|
|
354
|
-
* @param
|
|
355
|
-
* @param {Function} handler Обработчик события
|
|
356
|
-
* @param {WebSocketNamespace | string} [namespace] Пространство имен (если не указано, добавляется ко всем активным)
|
|
94
|
+
* Отписаться от событий мышления
|
|
95
|
+
* @param callback Функция обратного вызова для обработки событий мышления
|
|
357
96
|
*/
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
// Если указано пространство имен, добавляем обработчик только к нему
|
|
361
|
-
const namespaceEnum = this.resolveNamespace(namespace);
|
|
362
|
-
const client = this.clients.get(namespaceEnum);
|
|
363
|
-
if (!client) {
|
|
364
|
-
throw new Error(`Не подключен к пространству имен ${namespaceEnum}`);
|
|
365
|
-
}
|
|
366
|
-
client.on(eventType, handler);
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
// Если пространство имен не указано, добавляем обработчик ко всем активным пространствам
|
|
370
|
-
for (const client of this.clients.values()) {
|
|
371
|
-
client.on(eventType, handler);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
97
|
+
unsubscribeFromThinking(callback) {
|
|
98
|
+
this.off(websocket_events_constants_1.ReasoningEventNames.THINKING, callback);
|
|
374
99
|
}
|
|
375
100
|
/**
|
|
376
|
-
*
|
|
377
|
-
* @param {string}
|
|
378
|
-
* @
|
|
379
|
-
* @param {WebSocketNamespace | string} [namespace] Пространство имен (если не указано, удаляется из всех активных)
|
|
101
|
+
* Проверяет статус рассуждения
|
|
102
|
+
* @param {string} reasoningId ID рассуждения
|
|
103
|
+
* @returns {Promise<object>} Объект с информацией о статусе
|
|
380
104
|
*/
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const client = this.clients.get(namespaceEnum);
|
|
386
|
-
if (!client) {
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
client.off(eventType, handler);
|
|
105
|
+
async getReasoningStatus(reasoningId) {
|
|
106
|
+
const id = reasoningId || this.activeReasoningId;
|
|
107
|
+
if (!id) {
|
|
108
|
+
return { exists: false, isActive: false };
|
|
390
109
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
client.off(eventType, handler);
|
|
110
|
+
try {
|
|
111
|
+
if (!this.isConnected()) {
|
|
112
|
+
await this.connect();
|
|
395
113
|
}
|
|
114
|
+
const result = await this.emitWithAck(CUSTOM_EVENTS.GET_REASONING_STATUS, { reasoningId: id });
|
|
115
|
+
return result;
|
|
396
116
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
401
|
-
* @param {string} eventType Тип события
|
|
402
|
-
* @param {any} [data] Данные сообщения
|
|
403
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
404
|
-
*/
|
|
405
|
-
send(namespace, eventType, data) {
|
|
406
|
-
const client = this.clients.get(namespace);
|
|
407
|
-
if (!client) {
|
|
408
|
-
throw new Error(`Не подключен к пространству имен ${namespace}`);
|
|
409
|
-
}
|
|
410
|
-
return client.send({
|
|
411
|
-
event: eventType,
|
|
412
|
-
data
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Отправляет сообщение в активную сессию рассуждения
|
|
417
|
-
* @param {string} eventType Тип события
|
|
418
|
-
* @param {any} [data] Данные сообщения
|
|
419
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
420
|
-
*/
|
|
421
|
-
sendToReasoning(eventType, data) {
|
|
422
|
-
if (!this.activeReasoningId) {
|
|
423
|
-
throw new Error('Не подключен к сессии рассуждения');
|
|
117
|
+
catch (error) {
|
|
118
|
+
this.logger.error(`Ошибка при получении статуса рассуждения ${id}`, error);
|
|
119
|
+
return { exists: false, isActive: false };
|
|
424
120
|
}
|
|
425
|
-
return this.send(WebSocketNamespace.REASONING, eventType, data);
|
|
426
121
|
}
|
|
427
122
|
/**
|
|
428
|
-
*
|
|
429
|
-
* @param {string}
|
|
430
|
-
* @
|
|
431
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
123
|
+
* Проверяет существование рассуждения
|
|
124
|
+
* @param {string} reasoningId ID рассуждения
|
|
125
|
+
* @returns {Promise<boolean>} true, если рассуждение существует
|
|
432
126
|
*/
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
127
|
+
async checkReasoningExists(reasoningId) {
|
|
128
|
+
try {
|
|
129
|
+
const { exists } = await this.getReasoningStatus(reasoningId);
|
|
130
|
+
return exists;
|
|
436
131
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Отправляет сообщение в уведомления
|
|
441
|
-
* @param {string} eventType Тип события
|
|
442
|
-
* @param {any} [data] Данные сообщения
|
|
443
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
444
|
-
*/
|
|
445
|
-
sendToNotifications(eventType, data) {
|
|
446
|
-
return this.send(WebSocketNamespace.DEFAULT, eventType, data);
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Проверяет, подключен ли клиент к указанному пространству имен
|
|
450
|
-
* @param {WebSocketNamespace | string} namespace Пространство имен (WebSocketNamespace или строка)
|
|
451
|
-
* @returns {boolean} Статус подключения
|
|
452
|
-
*/
|
|
453
|
-
isConnected(namespace) {
|
|
454
|
-
// Преобразуем в перечисление
|
|
455
|
-
const namespaceEnum = this.resolveNamespace(namespace);
|
|
456
|
-
// Проверяем состояние подключения
|
|
457
|
-
const client = this.clients.get(namespaceEnum);
|
|
458
|
-
return client ? client.isConnected() : false;
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Проверяет, подключен ли клиент к пространству имен рассуждений
|
|
462
|
-
* @returns {boolean} Статус подключения
|
|
463
|
-
*/
|
|
464
|
-
isConnectedToReasoning() {
|
|
465
|
-
return this.isConnected(WebSocketNamespace.REASONING);
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Проверяет, подключен ли клиент к пространству имен индексации
|
|
469
|
-
* @returns {boolean} Статус подключения
|
|
470
|
-
*/
|
|
471
|
-
isConnectedToIndexing() {
|
|
472
|
-
return this.isConnected(WebSocketNamespace.INDEXING);
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Проверяет, подключен ли клиент к пространству имен уведомлений
|
|
476
|
-
* @returns {boolean} Статус подключения
|
|
477
|
-
*/
|
|
478
|
-
isConnectedToNotifications() {
|
|
479
|
-
return this.isConnected(WebSocketNamespace.DEFAULT);
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Получает ID сокета для указанного пространства имен
|
|
483
|
-
* @param {WebSocketNamespace} [namespace=WebSocketNamespace.REASONING] Пространство имен
|
|
484
|
-
* @returns {string|null} ID сокета или null, если соединение не установлено
|
|
485
|
-
*/
|
|
486
|
-
getSocketId(namespace = WebSocketNamespace.REASONING) {
|
|
487
|
-
const client = this.clients.get(namespace);
|
|
488
|
-
if (!client || !client.isConnected()) {
|
|
489
|
-
console.warn(`[WsClientWrapper] getSocketId: Нет активных соединений с Socket.IO сервером для ${namespace}`);
|
|
490
|
-
return null;
|
|
132
|
+
catch (error) {
|
|
133
|
+
return false;
|
|
491
134
|
}
|
|
492
|
-
return client.getSocketId();
|
|
493
135
|
}
|
|
494
136
|
/**
|
|
495
|
-
*
|
|
496
|
-
* @
|
|
497
|
-
* @param {Function} handler Обработчик событий мышления
|
|
498
|
-
* @returns {void}
|
|
137
|
+
* Получает ID активной сессии рассуждения
|
|
138
|
+
* @returns {string | null} ID активной сессии или null
|
|
499
139
|
*/
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
this.thinkingEventHandlers.set(reasoningId, handler);
|
|
503
|
-
// Получаем клиент рассуждений
|
|
504
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
505
|
-
if (!client) {
|
|
506
|
-
throw new Error('Не подключен к пространству имен рассуждения');
|
|
507
|
-
}
|
|
508
|
-
// Подписываемся на события мышления
|
|
509
|
-
client.on(`thinking:${reasoningId}`, (data) => {
|
|
510
|
-
handler(data);
|
|
511
|
-
});
|
|
512
|
-
// Дублируем подписку для полной совместимости
|
|
513
|
-
client.on(`reasoning:thinking:${reasoningId}`, (data) => {
|
|
514
|
-
handler(data);
|
|
515
|
-
});
|
|
140
|
+
getActiveReasoningId() {
|
|
141
|
+
return this.activeReasoningId;
|
|
516
142
|
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Специализированный WebSocket клиент для пространства имен indexing
|
|
146
|
+
*/
|
|
147
|
+
class IndexingWsClient extends base_ws_client_js_1.BaseWebSocketClient {
|
|
517
148
|
/**
|
|
518
|
-
*
|
|
519
|
-
* @param {string}
|
|
520
|
-
* @
|
|
149
|
+
* Создает новый WebSocket клиент для индексации
|
|
150
|
+
* @param {string} baseURL Базовый URL API
|
|
151
|
+
* @param {BaseWebSocketClientOptions} options Опции клиента
|
|
521
152
|
*/
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
527
|
-
if (!client)
|
|
528
|
-
return;
|
|
529
|
-
// Отписываемся от событий
|
|
530
|
-
client.off(`thinking:${reasoningId}`);
|
|
531
|
-
client.off(`reasoning:thinking:${reasoningId}`);
|
|
153
|
+
constructor(baseURL, options = {}) {
|
|
154
|
+
super(websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING, baseURL, options);
|
|
155
|
+
/** Активный проект */
|
|
156
|
+
this.activeProjectId = null;
|
|
532
157
|
}
|
|
533
158
|
/**
|
|
534
|
-
* Подключается к
|
|
535
|
-
* @param {string}
|
|
536
|
-
* @
|
|
537
|
-
* @returns {Promise<string>} Идентификатор сессии рассуждения
|
|
159
|
+
* Подключается к серверу WebSocket с указанным ID проекта
|
|
160
|
+
* @param {string} projectId ID проекта
|
|
161
|
+
* @returns {Promise<boolean>} Успешность подключения
|
|
538
162
|
*/
|
|
539
|
-
async
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
await this.connect(WebSocketNamespace.REASONING);
|
|
543
|
-
// Получаем клиент
|
|
544
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
545
|
-
if (!client) {
|
|
546
|
-
throw new Error(`Не удалось получить WebSocket клиент для ${WebSocketNamespace.REASONING}`);
|
|
547
|
-
}
|
|
548
|
-
// Если reasoningId == "system", сервер заменит его на новый
|
|
549
|
-
// с префиксом "system-". Для получения нового ID нужно подписаться
|
|
550
|
-
// на событие создания рассуждения.
|
|
551
|
-
if (reasoningId === "system") {
|
|
552
|
-
// Будем ждать ответа о создании рассуждения
|
|
553
|
-
return new Promise((resolve, reject) => {
|
|
554
|
-
// Устанавливаем таймаут
|
|
555
|
-
const timeout = setTimeout(() => {
|
|
556
|
-
reject(new Error('Таймаут ожидания ответа о создании рассуждения'));
|
|
557
|
-
}, 10000);
|
|
558
|
-
// Подписываемся на событие создания рассуждения
|
|
559
|
-
client.once(`${websocket_events_constants_js_1.WebSocketEvents.CREATE_REASONING}_response`, (data) => {
|
|
560
|
-
clearTimeout(timeout);
|
|
561
|
-
if (data.error) {
|
|
562
|
-
reject(new Error(`Ошибка создания рассуждения: ${data.error}`));
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
const newReasoningId = data.reasoningId;
|
|
566
|
-
this.activeReasoningId = newReasoningId;
|
|
567
|
-
// Отправляем запрос на присоединение к сессии рассуждения
|
|
568
|
-
client.sendSocketIOEvent(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, { reasoningId: newReasoningId }, (joinResponse) => {
|
|
569
|
-
if (joinResponse.success === false) {
|
|
570
|
-
reject(new Error(`Ошибка при присоединении к сессии рассуждения: ${joinResponse.error || 'Неизвестная ошибка'}`));
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
// Отправляем запрос на запуск рассуждения
|
|
574
|
-
client.sendSocketIOEvent(websocket_events_constants_js_1.WebSocketEvents.START_REASONING, { reasoningId: newReasoningId }, (startResponse) => {
|
|
575
|
-
if (startResponse.success === false) {
|
|
576
|
-
reject(new Error(`Ошибка при запуске рассуждения: ${startResponse.error || 'Неизвестная ошибка'}`));
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
// Если передан обработчик событий мышления, подписываемся
|
|
580
|
-
if (thinkingHandler) {
|
|
581
|
-
this.subscribeToThinking(newReasoningId, thinkingHandler);
|
|
582
|
-
}
|
|
583
|
-
resolve(newReasoningId);
|
|
584
|
-
}, this.namespace);
|
|
585
|
-
}, this.namespace);
|
|
586
|
-
});
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
this.activeReasoningId = reasoningId;
|
|
591
|
-
// Отправляем запрос на присоединение к сессии рассуждения
|
|
592
|
-
return new Promise((resolve, reject) => {
|
|
593
|
-
client.sendSocketIOEvent(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, { reasoningId }, (joinResponse) => {
|
|
594
|
-
if (joinResponse.success === false) {
|
|
595
|
-
reject(new Error(`Ошибка при присоединении к сессии рассуждения: ${joinResponse.error || 'Неизвестная ошибка'}`));
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
598
|
-
// Отправляем запрос на запуск рассуждения
|
|
599
|
-
client.sendSocketIOEvent(websocket_events_constants_js_1.WebSocketEvents.START_REASONING, { reasoningId }, (startResponse) => {
|
|
600
|
-
if (startResponse.success === false) {
|
|
601
|
-
reject(new Error(`Ошибка при запуске рассуждения: ${startResponse.error || 'Неизвестная ошибка'}`));
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
// Если передан обработчик событий мышления, подписываемся
|
|
605
|
-
if (thinkingHandler) {
|
|
606
|
-
this.subscribeToThinking(reasoningId, thinkingHandler);
|
|
607
|
-
}
|
|
608
|
-
resolve(reasoningId);
|
|
609
|
-
}, this.namespace);
|
|
610
|
-
}, this.namespace);
|
|
611
|
-
});
|
|
612
|
-
}
|
|
163
|
+
async connectWithProject(projectId) {
|
|
164
|
+
if (projectId) {
|
|
165
|
+
this.activeProjectId = projectId;
|
|
613
166
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Настраивает отладочное логирование для WebSocket клиента
|
|
620
|
-
* @param namespace Пространство имен
|
|
621
|
-
*/
|
|
622
|
-
setupDebugLogging(namespace) {
|
|
623
|
-
const client = this.clients.get(namespace);
|
|
624
|
-
if (!client)
|
|
625
|
-
return;
|
|
626
|
-
// Добавляем детальное логирование всех событий
|
|
627
|
-
client.on('socket.io_event', (data) => {
|
|
628
|
-
this.logger('debug', `[WS:${namespace}] Получено Socket.IO событие: ${data.event}`, data.data);
|
|
629
|
-
});
|
|
630
|
-
// Добавляем обработчик для всех событий (onAny)
|
|
631
|
-
client.on('message', (data) => {
|
|
632
|
-
if (typeof data === 'string') {
|
|
633
|
-
try {
|
|
634
|
-
this.logger('debug', `[WS:${namespace}] Получено сырое сообщение`, data);
|
|
635
|
-
}
|
|
636
|
-
catch (e) {
|
|
637
|
-
this.logger('error', `[WS:${namespace}] Ошибка при обработке сырого сообщения`, data);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
// Отслеживаем состояние соединения
|
|
642
|
-
client.on('connect', () => {
|
|
643
|
-
this.logger('info', `[WS:${namespace}] Соединение установлено`);
|
|
644
|
-
});
|
|
645
|
-
client.on('close', (data) => {
|
|
646
|
-
this.logger('info', `[WS:${namespace}] Соединение закрыто: ${data.code}, Причина: ${data.reason}`);
|
|
647
|
-
});
|
|
648
|
-
client.on('error', (error) => {
|
|
649
|
-
this.logger('error', `[WS:${namespace}] Ошибка соединения`, error);
|
|
650
|
-
});
|
|
651
|
-
// Отслеживаем ping/pong для проверки состояния соединения
|
|
652
|
-
client.on('ping', () => this.logger('debug', `[WS:${namespace}] Отправлен ping`));
|
|
653
|
-
client.on('pong', () => this.logger('debug', `[WS:${namespace}] Получен pong`));
|
|
654
|
-
// Добавляем обработчик для отслеживания ответов на события
|
|
655
|
-
client.on('socket.io_raw', (data) => {
|
|
656
|
-
this.logger('debug', `[WS:${namespace}] Socket.IO raw пакет`, { type: data.type, data: data.data });
|
|
167
|
+
return super.connect({
|
|
168
|
+
projectId: this.activeProjectId
|
|
657
169
|
});
|
|
658
170
|
}
|
|
659
171
|
/**
|
|
660
|
-
*
|
|
661
|
-
* @
|
|
662
|
-
* @param data Данные события
|
|
663
|
-
* @private
|
|
172
|
+
* Получает ID активного проекта
|
|
173
|
+
* @returns {string | null} ID активного проекта или null
|
|
664
174
|
*/
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
try {
|
|
668
|
-
// Копируем данные без callback
|
|
669
|
-
const dataCopy = { ...data };
|
|
670
|
-
delete dataCopy.callback;
|
|
671
|
-
// Получаем callback-функцию
|
|
672
|
-
const callback = data.callback;
|
|
673
|
-
// Вызываем callback
|
|
674
|
-
this.logger('debug', `Вызов callback для события ${eventName}`);
|
|
675
|
-
// Создаем таймаут для предотвращения зависания
|
|
676
|
-
const timeoutId = setTimeout(() => {
|
|
677
|
-
this.logger('warn', `Таймаут выполнения callback для события ${eventName}`);
|
|
678
|
-
}, 5000);
|
|
679
|
-
// Вызываем callback и очищаем таймаут
|
|
680
|
-
callback();
|
|
681
|
-
clearTimeout(timeoutId);
|
|
682
|
-
}
|
|
683
|
-
catch (error) {
|
|
684
|
-
this.logger('error', `Ошибка при вызове callback для события ${eventName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
175
|
+
getActiveProjectId() {
|
|
176
|
+
return this.activeProjectId;
|
|
687
177
|
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Специализированный WebSocket клиент для пространства имен dependencies
|
|
181
|
+
*/
|
|
182
|
+
class DependenciesWsClient extends base_ws_client_js_1.BaseWebSocketClient {
|
|
688
183
|
/**
|
|
689
|
-
*
|
|
690
|
-
* @param {
|
|
691
|
-
* @param {
|
|
692
|
-
* @returns {boolean} - Успешность включения ping/pong
|
|
184
|
+
* Создает новый WebSocket клиент для зависимостей
|
|
185
|
+
* @param {string} baseURL Базовый URL API
|
|
186
|
+
* @param {BaseWebSocketClientOptions} options Опции клиента
|
|
693
187
|
*/
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
this.timeoutThreshold = timeoutThreshold;
|
|
697
|
-
// Для каждого активного соединения
|
|
698
|
-
for (const [namespace, client] of this.clients.entries()) {
|
|
699
|
-
try {
|
|
700
|
-
// Проверяем, активно ли соединение
|
|
701
|
-
if (!client || !this.isConnected(namespace)) {
|
|
702
|
-
this.logger('warn', `Невозможно включить ping/pong для неактивного соединения в ${namespace}`);
|
|
703
|
-
continue;
|
|
704
|
-
}
|
|
705
|
-
// Останавливаем существующий таймер, если есть
|
|
706
|
-
this.disablePingPong(namespace);
|
|
707
|
-
// Инициализируем статистику, если не была создана
|
|
708
|
-
if (!this.pingStats.has(namespace)) {
|
|
709
|
-
this.pingStats.set(namespace, {
|
|
710
|
-
namespace,
|
|
711
|
-
socketId: client.getSocketId(),
|
|
712
|
-
pingSent: 0,
|
|
713
|
-
pongReceived: 0,
|
|
714
|
-
averageRtt: 0,
|
|
715
|
-
minRtt: Number.MAX_SAFE_INTEGER,
|
|
716
|
-
maxRtt: 0,
|
|
717
|
-
lastRtt: 0,
|
|
718
|
-
lastPongTimestamp: Date.now(),
|
|
719
|
-
isConnected: true
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
// Сбрасываем счетчик таймаутов
|
|
723
|
-
this.pingTimeouts.set(namespace, 0);
|
|
724
|
-
// Устанавливаем обработчик для события connection_pong
|
|
725
|
-
client.on(websocket_events_constants_js_1.WebSocketEvents.CONNECTION_PONG, (data) => {
|
|
726
|
-
// Обновляем статистику
|
|
727
|
-
const stats = this.pingStats.get(namespace);
|
|
728
|
-
if (stats) {
|
|
729
|
-
stats.pongReceived++;
|
|
730
|
-
stats.lastPongTimestamp = Date.now();
|
|
731
|
-
stats.isConnected = true;
|
|
732
|
-
// Рассчитываем RTT, если есть метка времени эхо
|
|
733
|
-
if (data && data.echo) {
|
|
734
|
-
const rtt = Date.now() - data.echo;
|
|
735
|
-
stats.lastRtt = rtt;
|
|
736
|
-
// Обновляем min и max
|
|
737
|
-
stats.minRtt = Math.min(stats.minRtt, rtt);
|
|
738
|
-
stats.maxRtt = Math.max(stats.maxRtt, rtt);
|
|
739
|
-
// Обновляем среднее значение
|
|
740
|
-
stats.averageRtt = (stats.averageRtt * (stats.pongReceived - 1) + rtt) / stats.pongReceived;
|
|
741
|
-
}
|
|
742
|
-
// Сбрасываем счетчик таймаутов
|
|
743
|
-
this.pingTimeouts.set(namespace, 0);
|
|
744
|
-
}
|
|
745
|
-
// Логируем получение pong
|
|
746
|
-
this.logger('debug', `Получен pong для ${namespace}`, {
|
|
747
|
-
rtt: stats?.lastRtt,
|
|
748
|
-
socketId: client.getSocketId()
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
-
// Устанавливаем интервал отправки ping
|
|
752
|
-
const pingInterval = setInterval(() => {
|
|
753
|
-
if (this.isConnected(namespace)) {
|
|
754
|
-
// Формируем данные ping
|
|
755
|
-
const pingData = { timestamp: Date.now() };
|
|
756
|
-
// Отправляем ping
|
|
757
|
-
const sent = this.send(namespace, websocket_events_constants_js_1.WebSocketEvents.CONNECTION_PING, pingData);
|
|
758
|
-
// Если успешно отправлено, обновляем статистику
|
|
759
|
-
if (sent) {
|
|
760
|
-
const stats = this.pingStats.get(namespace);
|
|
761
|
-
if (stats) {
|
|
762
|
-
stats.pingSent++;
|
|
763
|
-
}
|
|
764
|
-
this.logger('debug', `Отправлен ping для ${namespace}`, pingData);
|
|
765
|
-
}
|
|
766
|
-
else {
|
|
767
|
-
this.logger('warn', `Не удалось отправить ping для ${namespace}`);
|
|
768
|
-
}
|
|
769
|
-
// Проверяем таймаут
|
|
770
|
-
const timeouts = this.pingTimeouts.get(namespace) || 0;
|
|
771
|
-
const stats = this.pingStats.get(namespace);
|
|
772
|
-
// Если разница между отправленными и полученными превышает порог,
|
|
773
|
-
// или последний pong был получен слишком давно
|
|
774
|
-
if ((stats && stats.pingSent - stats.pongReceived > this.timeoutThreshold) ||
|
|
775
|
-
(stats && Date.now() - stats.lastPongTimestamp > interval * this.timeoutThreshold)) {
|
|
776
|
-
// Увеличиваем счетчик таймаутов
|
|
777
|
-
this.pingTimeouts.set(namespace, timeouts + 1);
|
|
778
|
-
if (timeouts + 1 >= this.timeoutThreshold) {
|
|
779
|
-
// Соединение потеряно
|
|
780
|
-
this.logger('error', `Соединение потеряно (таймаут ping/pong) для ${namespace}`);
|
|
781
|
-
// Установка флага неактивного соединения
|
|
782
|
-
if (stats) {
|
|
783
|
-
stats.isConnected = false;
|
|
784
|
-
}
|
|
785
|
-
// На прямую отправку события через socket
|
|
786
|
-
this.send(namespace, 'connection_timeout', {
|
|
787
|
-
namespace,
|
|
788
|
-
socketId: client.getSocketId(),
|
|
789
|
-
timeouts: timeouts + 1,
|
|
790
|
-
threshold: this.timeoutThreshold
|
|
791
|
-
});
|
|
792
|
-
// Также вызываем обработчики событий
|
|
793
|
-
const timeoutHandlers = this.pingPongEventHandlers.get('connection_timeout') || [];
|
|
794
|
-
timeoutHandlers.forEach(handler => {
|
|
795
|
-
try {
|
|
796
|
-
handler({
|
|
797
|
-
namespace,
|
|
798
|
-
socketId: client.getSocketId(),
|
|
799
|
-
timeouts: timeouts + 1,
|
|
800
|
-
threshold: this.timeoutThreshold
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
catch (error) {
|
|
804
|
-
this.logger('error', `Ошибка при обработке события connection_timeout`, error);
|
|
805
|
-
}
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}, interval);
|
|
811
|
-
// Сохраняем интервал
|
|
812
|
-
this.pingIntervals.set(namespace, pingInterval);
|
|
813
|
-
this.logger('info', `Включен механизм ping/pong для ${namespace} с интервалом ${interval}ms`);
|
|
814
|
-
}
|
|
815
|
-
catch (error) {
|
|
816
|
-
this.logger('error', `Ошибка при включении ping/pong для ${namespace}`, error);
|
|
817
|
-
return false;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
return true;
|
|
188
|
+
constructor(baseURL, options = {}) {
|
|
189
|
+
super(websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES, baseURL, options);
|
|
821
190
|
}
|
|
822
191
|
/**
|
|
823
|
-
*
|
|
824
|
-
* @param {
|
|
192
|
+
* Подключается к серверу WebSocket с указанным ID проекта
|
|
193
|
+
* @param {string} projectId ID проекта
|
|
194
|
+
* @returns {Promise<boolean>} Успешность подключения
|
|
825
195
|
*/
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
// Отключаем для указанного namespace
|
|
829
|
-
const interval = this.pingIntervals.get(namespace);
|
|
830
|
-
if (interval) {
|
|
831
|
-
clearInterval(interval);
|
|
832
|
-
this.pingIntervals.delete(namespace);
|
|
833
|
-
this.logger('info', `Отключен механизм ping/pong для ${namespace}`);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
else {
|
|
837
|
-
// Отключаем для всех namespace
|
|
838
|
-
for (const [ns, interval] of this.pingIntervals.entries()) {
|
|
839
|
-
clearInterval(interval);
|
|
840
|
-
this.pingIntervals.delete(ns);
|
|
841
|
-
this.logger('info', `Отключен механизм ping/pong для ${ns}`);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
196
|
+
async connectWithProject(projectId) {
|
|
197
|
+
return super.connect({ projectId });
|
|
844
198
|
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Специализированный WebSocket клиент для пространства имен notifications
|
|
202
|
+
*/
|
|
203
|
+
class NotificationsWsClient extends base_ws_client_js_1.BaseWebSocketClient {
|
|
845
204
|
/**
|
|
846
|
-
*
|
|
847
|
-
* @param {
|
|
848
|
-
* @
|
|
205
|
+
* Создает новый WebSocket клиент для уведомлений
|
|
206
|
+
* @param {string} baseURL Базовый URL API
|
|
207
|
+
* @param {BaseWebSocketClientOptions} options Опции клиента
|
|
849
208
|
*/
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
// Возвращаем статистику для указанного namespace
|
|
853
|
-
return this.pingStats.get(namespace) || null;
|
|
854
|
-
}
|
|
855
|
-
else {
|
|
856
|
-
// Возвращаем статистику для всех namespace
|
|
857
|
-
return Array.from(this.pingStats.values());
|
|
858
|
-
}
|
|
209
|
+
constructor(baseURL, options = {}) {
|
|
210
|
+
super(websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT, baseURL, options);
|
|
859
211
|
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Сервис для диагностики WebSocket соединений
|
|
215
|
+
*/
|
|
216
|
+
class DiagnosticsService {
|
|
860
217
|
/**
|
|
861
|
-
*
|
|
862
|
-
* @param {
|
|
863
|
-
* @param {(data: any) => void} handler - Обработчик события
|
|
218
|
+
* Создает новый сервис диагностики
|
|
219
|
+
* @param {DiagnosticsServiceOptions} options Опции сервиса
|
|
864
220
|
*/
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
}
|
|
869
|
-
const handlers = this.pingPongEventHandlers.get(eventType);
|
|
870
|
-
if (handlers) {
|
|
871
|
-
handlers.push(handler);
|
|
872
|
-
}
|
|
221
|
+
constructor(options) {
|
|
222
|
+
this.clients = options.clients;
|
|
223
|
+
this.logger = options.logger;
|
|
873
224
|
}
|
|
874
225
|
/**
|
|
875
|
-
*
|
|
876
|
-
* @
|
|
877
|
-
* @param {(data: any) => void} [handler] - Обработчик события (если не указан, удаляются все обработчики)
|
|
226
|
+
* Получает диагностическую информацию о всех соединениях
|
|
227
|
+
* @returns {object} Диагностическая информация
|
|
878
228
|
*/
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
const index = handlers.findIndex(h => h === handler);
|
|
889
|
-
if (index !== -1) {
|
|
890
|
-
handlers.splice(index, 1);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
229
|
+
getDiagnostics() {
|
|
230
|
+
const result = {};
|
|
231
|
+
// Собираем информацию о каждом соединении
|
|
232
|
+
for (const [namespace, client] of Object.entries(this.clients)) {
|
|
233
|
+
result[namespace] = {
|
|
234
|
+
isConnected: client.isConnected(),
|
|
235
|
+
socketId: client.getSocketId()
|
|
236
|
+
// При необходимости можно добавить дополнительную информацию
|
|
237
|
+
};
|
|
893
238
|
}
|
|
239
|
+
return result;
|
|
894
240
|
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* WebSocket клиент для работы с Code Solver API (фасад)
|
|
244
|
+
*/
|
|
245
|
+
class CodeSolverWebSocketClient {
|
|
895
246
|
/**
|
|
896
|
-
*
|
|
897
|
-
* @
|
|
247
|
+
* Создает новый WebSocket клиент для Code Solver API
|
|
248
|
+
* @param {string} baseURL Базовый URL API
|
|
249
|
+
* @param {CodeSolverWebSocketOptions} [options] Опции клиента
|
|
898
250
|
*/
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
251
|
+
constructor(baseURL, options = {}) {
|
|
252
|
+
this.baseURL = baseURL.replace(/^http/, 'ws');
|
|
253
|
+
this.options = {
|
|
254
|
+
...options,
|
|
255
|
+
headers: {
|
|
256
|
+
...(options.headers || {}),
|
|
257
|
+
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {})
|
|
905
258
|
}
|
|
906
|
-
return -1;
|
|
907
259
|
};
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
return {
|
|
920
|
-
namespace,
|
|
921
|
-
isConnected: client?.isConnected() || false,
|
|
922
|
-
socketId: client?.getSocketId() || null,
|
|
923
|
-
lastActivity: stats?.lastPongTimestamp || 0,
|
|
924
|
-
rtt: {
|
|
925
|
-
current: stats?.lastRtt || -1,
|
|
926
|
-
min: stats?.minRtt === Number.MAX_SAFE_INTEGER ? -1 : (stats?.minRtt || -1),
|
|
927
|
-
max: stats?.maxRtt || -1,
|
|
928
|
-
avg: stats?.averageRtt || -1
|
|
929
|
-
},
|
|
930
|
-
pingSent: stats?.pingSent || 0,
|
|
931
|
-
pongReceived: stats?.pongReceived || 0,
|
|
932
|
-
missedPongs: (stats?.pingSent || 0) - (stats?.pongReceived || 0),
|
|
933
|
-
timeoutCount: this.pingTimeouts.get(namespace) || 0,
|
|
934
|
-
reconnectAttempts: connectionState.reconnectAttempts,
|
|
935
|
-
lastConnectTime: connectionState.lastConnectTime,
|
|
936
|
-
sessionRecovery: {
|
|
937
|
-
hasSessionToken: !!sessionToken,
|
|
938
|
-
tokenLength: sessionToken?.length || 0,
|
|
939
|
-
wasRecovered: !!sessionToken && (stats?.pongReceived || 0) > 0
|
|
940
|
-
}
|
|
260
|
+
// Создаем логгер
|
|
261
|
+
this.logger = (0, logger_js_1.createWebSocketLogger)('CodeSolverWebSocket');
|
|
262
|
+
// Трансформируем опции для специализированных клиентов
|
|
263
|
+
const clientOptions = {
|
|
264
|
+
...this.options,
|
|
265
|
+
enableAutoPing: options.enableAutoPing !== false,
|
|
266
|
+
enableSessionPersistence: options.enableSessionPersistence !== false,
|
|
267
|
+
// Преобразуем функцию логгера в экземпляр Logger, если передана функция
|
|
268
|
+
logger: typeof options.logger === 'function' ?
|
|
269
|
+
(0, logger_js_1.createWebSocketLogger)('CodeSolverWebSocket', options.logger) :
|
|
270
|
+
options.logger
|
|
941
271
|
};
|
|
272
|
+
// Создаем специализированные клиенты
|
|
273
|
+
this.reasoningClient = new ReasoningWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Reasoning') });
|
|
274
|
+
this.indexingClient = new IndexingWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Indexing') });
|
|
275
|
+
this.dependenciesClient = new DependenciesWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Dependencies') });
|
|
276
|
+
this.notificationsClient = new NotificationsWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Notifications') });
|
|
277
|
+
// Создаем сервис диагностики
|
|
278
|
+
this.diagnosticsService = new DiagnosticsService({
|
|
279
|
+
clients: {
|
|
280
|
+
[websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING]: this.reasoningClient,
|
|
281
|
+
[websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING]: this.indexingClient,
|
|
282
|
+
[websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES]: this.dependenciesClient,
|
|
283
|
+
[websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT]: this.notificationsClient
|
|
284
|
+
},
|
|
285
|
+
logger: this.logger.withPrefix('Diagnostics')
|
|
286
|
+
});
|
|
942
287
|
}
|
|
943
288
|
/**
|
|
944
|
-
*
|
|
945
|
-
* @
|
|
289
|
+
* Подключается к пространству имен рассуждений
|
|
290
|
+
* @param {string} reasoningId ID рассуждения (опционально)
|
|
291
|
+
* @param {object} options Дополнительные настройки подключения
|
|
292
|
+
* @returns {Promise<boolean>} Результат подключения
|
|
946
293
|
*/
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
// Проверяем каждое возможное пространство имен
|
|
950
|
-
for (const namespace of Object.values(WebSocketNamespace)) {
|
|
951
|
-
if (this.clients.has(namespace)) {
|
|
952
|
-
result[String(namespace)] = this.diagnoseConnection(namespace);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
return result;
|
|
294
|
+
async connectToReasoning(reasoningId, options = {}) {
|
|
295
|
+
return this.reasoningClient.connectWithReasoning(reasoningId, options);
|
|
956
296
|
}
|
|
957
297
|
/**
|
|
958
|
-
*
|
|
959
|
-
* @param {
|
|
960
|
-
* @returns {
|
|
298
|
+
* Подключается к пространству имен индексации
|
|
299
|
+
* @param {string} projectId ID проекта (опционально)
|
|
300
|
+
* @returns {Promise<boolean>} Результат подключения
|
|
961
301
|
*/
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const attempts = state.reconnectAttempts;
|
|
965
|
-
const strategy = this.options.reconnectStrategy || 'exponential';
|
|
966
|
-
const baseDelay = this.options.retryDelay || 1000;
|
|
967
|
-
const maxDelay = this.options.maxRetryDelay || 30000;
|
|
968
|
-
if (strategy === 'exponential') {
|
|
969
|
-
// Экспоненциальный рост с фактором 1.5
|
|
970
|
-
const calculatedDelay = Math.min(baseDelay * Math.pow(1.5, attempts), maxDelay);
|
|
971
|
-
// Добавляем случайный фактор (jitter) для предотвращения штормов переподключений
|
|
972
|
-
return calculatedDelay * (0.8 + Math.random() * 0.4);
|
|
973
|
-
}
|
|
974
|
-
else {
|
|
975
|
-
// Линейный рост
|
|
976
|
-
return Math.min(baseDelay * (attempts + 1), maxDelay);
|
|
977
|
-
}
|
|
302
|
+
async connectToIndexing(projectId) {
|
|
303
|
+
return this.indexingClient.connectWithProject(projectId);
|
|
978
304
|
}
|
|
979
305
|
/**
|
|
980
|
-
*
|
|
981
|
-
* @
|
|
982
|
-
* @param {boolean} immediate Выполнить переподключение немедленно, без задержки
|
|
983
|
-
* @returns {Promise<boolean>} Успешность операции
|
|
306
|
+
* Подключается к уведомлениям
|
|
307
|
+
* @returns {Promise<boolean>} Результат подключения
|
|
984
308
|
*/
|
|
985
|
-
async
|
|
986
|
-
|
|
987
|
-
try {
|
|
988
|
-
// Если клиент уже существует, закрываем его
|
|
989
|
-
if (client) {
|
|
990
|
-
this.logger('info', `Принудительное переподключение для ${namespace}`);
|
|
991
|
-
try {
|
|
992
|
-
// Отключаем ping/pong для этого namespace
|
|
993
|
-
this.disablePingPong(namespace);
|
|
994
|
-
// Закрываем соединение
|
|
995
|
-
client.close();
|
|
996
|
-
}
|
|
997
|
-
catch (e) {
|
|
998
|
-
this.logger('warn', `Ошибка при закрытии соединения с ${namespace}: ${e instanceof Error ? e.message : String(e)}`);
|
|
999
|
-
}
|
|
1000
|
-
// Удаляем клиент из кэша
|
|
1001
|
-
this.clients.delete(namespace);
|
|
1002
|
-
}
|
|
1003
|
-
else {
|
|
1004
|
-
this.logger('info', `Инициируем новое подключение для ${namespace}`);
|
|
1005
|
-
}
|
|
1006
|
-
// Устанавливаем состояние переподключения
|
|
1007
|
-
this.setConnectionState(namespace, false, true);
|
|
1008
|
-
// Инкрементируем счетчик попыток
|
|
1009
|
-
this.incrementReconnectAttempts(namespace);
|
|
1010
|
-
// Рассчитываем задержку, если не требуется немедленное переподключение
|
|
1011
|
-
if (!immediate) {
|
|
1012
|
-
const delay = this.calculateReconnectDelay(namespace);
|
|
1013
|
-
this.logger('info', `Переподключение для ${namespace} через ${delay}ms (попытка ${this.getConnectionState(namespace).reconnectAttempts})`);
|
|
1014
|
-
// Ждем рассчитанное время
|
|
1015
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
1016
|
-
}
|
|
1017
|
-
// Выполняем подключение с соответствующими параметрами
|
|
1018
|
-
let params = {};
|
|
1019
|
-
// Проверяем тип пространства имен и добавляем соответствующие параметры
|
|
1020
|
-
if (namespace === WebSocketNamespace.REASONING && this.activeReasoningId) {
|
|
1021
|
-
params.reasoningId = this.activeReasoningId;
|
|
1022
|
-
}
|
|
1023
|
-
else if ((namespace === WebSocketNamespace.INDEXING || namespace === WebSocketNamespace.DEPENDENCIES) && this.activeProjectId) {
|
|
1024
|
-
params.projectId = this.activeProjectId;
|
|
1025
|
-
}
|
|
1026
|
-
// Подключаемся
|
|
1027
|
-
await this.connect(namespace, params);
|
|
1028
|
-
// Если это пространство имен рассуждений и есть активное рассуждение,
|
|
1029
|
-
// пытаемся присоединиться к нему
|
|
1030
|
-
if (namespace === WebSocketNamespace.REASONING && this.activeReasoningId) {
|
|
1031
|
-
await this.connectToReasoning(this.activeReasoningId);
|
|
1032
|
-
}
|
|
1033
|
-
else if (namespace === WebSocketNamespace.INDEXING && this.activeProjectId) {
|
|
1034
|
-
await this.connectToIndexing();
|
|
1035
|
-
}
|
|
1036
|
-
else if (namespace === WebSocketNamespace.DEPENDENCIES && this.activeProjectId) {
|
|
1037
|
-
await this.connectToDependencies(this.activeProjectId);
|
|
1038
|
-
}
|
|
1039
|
-
return true;
|
|
1040
|
-
}
|
|
1041
|
-
catch (error) {
|
|
1042
|
-
this.logger('error', `Ошибка при переподключении к ${namespace}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1043
|
-
return false;
|
|
1044
|
-
}
|
|
309
|
+
async connectToNotifications() {
|
|
310
|
+
return this.notificationsClient.connect({});
|
|
1045
311
|
}
|
|
1046
312
|
/**
|
|
1047
|
-
*
|
|
1048
|
-
* @param {
|
|
313
|
+
* Подключается к пространству имен dependencies
|
|
314
|
+
* @param {string} projectId ID проекта (опционально)
|
|
315
|
+
* @returns {Promise<boolean>} Результат подключения
|
|
1049
316
|
*/
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
if (this.healthCheckTimer) {
|
|
1053
|
-
clearInterval(this.healthCheckTimer);
|
|
1054
|
-
}
|
|
1055
|
-
this.healthCheckTimer = setInterval(() => {
|
|
1056
|
-
for (const namespace of Object.values(WebSocketNamespace)) {
|
|
1057
|
-
const typedNamespace = namespace;
|
|
1058
|
-
const client = this.clients.get(typedNamespace);
|
|
1059
|
-
if (!client)
|
|
1060
|
-
continue;
|
|
1061
|
-
// Проверяем соединение через WebSocket клиент
|
|
1062
|
-
if (!client.isConnected()) {
|
|
1063
|
-
this.logger('warn', `Соединение с ${namespace} не активно, инициируем переподключение`);
|
|
1064
|
-
this.reconnectNamespace(typedNamespace, false).catch(() => { });
|
|
1065
|
-
continue;
|
|
1066
|
-
}
|
|
1067
|
-
// Проверяем статистику ping/pong
|
|
1068
|
-
const stats = this.pingStats.get(typedNamespace);
|
|
1069
|
-
if (stats) {
|
|
1070
|
-
const now = Date.now();
|
|
1071
|
-
// Если последний pong был получен слишком давно
|
|
1072
|
-
if (now - stats.lastPongTimestamp > interval * 2) {
|
|
1073
|
-
this.logger('warn', `Долгое отсутствие активности для ${namespace}, проверка соединения...`);
|
|
1074
|
-
// Отправляем проверочный ping
|
|
1075
|
-
this.send(typedNamespace, 'connection_health_check', { timestamp: now, echo: now });
|
|
1076
|
-
// Устанавливаем таймаут для проверки ответа
|
|
1077
|
-
setTimeout(() => {
|
|
1078
|
-
const currentStats = this.pingStats.get(typedNamespace);
|
|
1079
|
-
if (currentStats && now - currentStats.lastPongTimestamp > interval * 2) {
|
|
1080
|
-
this.logger('error', `Соединение не отвечает для ${namespace}, инициируем переподключение`);
|
|
1081
|
-
this.reconnectNamespace(typedNamespace, false).catch(() => { });
|
|
1082
|
-
}
|
|
1083
|
-
}, 5000); // Ждем 5 секунд на ответ
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}, interval);
|
|
1088
|
-
this.logger('info', 'Настроена периодическая проверка здоровья соединения с интервалом ' + interval + 'ms');
|
|
317
|
+
async connectToDependencies(projectId) {
|
|
318
|
+
return this.dependenciesClient.connectWithProject(projectId);
|
|
1089
319
|
}
|
|
1090
320
|
/**
|
|
1091
|
-
*
|
|
321
|
+
* Отключается от пространства имен
|
|
1092
322
|
* @param {WebSocketNamespace} namespace Пространство имен
|
|
1093
|
-
* @param {string} token Токен сессии
|
|
1094
323
|
*/
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
324
|
+
disconnect(namespace) {
|
|
325
|
+
switch (namespace) {
|
|
326
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
327
|
+
this.reasoningClient.disconnect();
|
|
328
|
+
break;
|
|
329
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
330
|
+
this.indexingClient.disconnect();
|
|
331
|
+
break;
|
|
332
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
333
|
+
this.dependenciesClient.disconnect();
|
|
334
|
+
break;
|
|
335
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
336
|
+
this.notificationsClient.disconnect();
|
|
337
|
+
break;
|
|
1099
338
|
}
|
|
1100
339
|
}
|
|
1101
340
|
/**
|
|
1102
|
-
*
|
|
1103
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
1104
|
-
* @returns {string | null} Токен сессии или null, если не найден
|
|
341
|
+
* Отключается от всех пространств имен
|
|
1105
342
|
*/
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
343
|
+
disconnectAll() {
|
|
344
|
+
this.reasoningClient.disconnect();
|
|
345
|
+
this.indexingClient.disconnect();
|
|
346
|
+
this.dependenciesClient.disconnect();
|
|
347
|
+
this.notificationsClient.disconnect();
|
|
1111
348
|
}
|
|
1112
349
|
/**
|
|
1113
|
-
*
|
|
350
|
+
* Проверяет, подключен ли клиент к указанному пространству имен
|
|
1114
351
|
* @param {WebSocketNamespace} namespace Пространство имен
|
|
352
|
+
* @returns {boolean} Статус подключения
|
|
1115
353
|
*/
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
354
|
+
isConnected(namespace) {
|
|
355
|
+
switch (namespace) {
|
|
356
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
357
|
+
return this.reasoningClient.isConnected();
|
|
358
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
359
|
+
return this.indexingClient.isConnected();
|
|
360
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
361
|
+
return this.dependenciesClient.isConnected();
|
|
362
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
363
|
+
return this.notificationsClient.isConnected();
|
|
364
|
+
default:
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
1119
367
|
}
|
|
1120
368
|
/**
|
|
1121
|
-
*
|
|
1122
|
-
* @
|
|
1123
|
-
* @param {boolean} connected Состояние подключения
|
|
1124
|
-
* @param {boolean} reconnecting Состояние переподключения
|
|
369
|
+
* Проверяет, подключен ли клиент к пространству имен рассуждений
|
|
370
|
+
* @returns {boolean} Статус подключения
|
|
1125
371
|
*/
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
state.connected = connected;
|
|
1129
|
-
state.reconnecting = reconnecting;
|
|
1130
|
-
if (connected) {
|
|
1131
|
-
state.lastConnectTime = Date.now();
|
|
1132
|
-
state.reconnectAttempts = 0;
|
|
1133
|
-
}
|
|
1134
|
-
this.connectionState.set(namespace, state);
|
|
372
|
+
isConnectedToReasoning() {
|
|
373
|
+
return this.reasoningClient.isConnected();
|
|
1135
374
|
}
|
|
1136
375
|
/**
|
|
1137
|
-
*
|
|
1138
|
-
* @
|
|
1139
|
-
* @returns {number} Новое количество попыток
|
|
376
|
+
* Проверяет, подключен ли клиент к пространству имен индексации
|
|
377
|
+
* @returns {boolean} Статус подключения
|
|
1140
378
|
*/
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
state.reconnectAttempts++;
|
|
1144
|
-
state.reconnecting = true;
|
|
1145
|
-
this.connectionState.set(namespace, state);
|
|
1146
|
-
return state.reconnectAttempts;
|
|
379
|
+
isConnectedToIndexing() {
|
|
380
|
+
return this.indexingClient.isConnected();
|
|
1147
381
|
}
|
|
1148
382
|
/**
|
|
1149
|
-
*
|
|
1150
|
-
* @
|
|
1151
|
-
* @returns {object} Состояние подключения
|
|
383
|
+
* Проверяет, подключен ли клиент к пространству имен уведомлений
|
|
384
|
+
* @returns {boolean} Статус подключения
|
|
1152
385
|
*/
|
|
1153
|
-
|
|
1154
|
-
return this.
|
|
1155
|
-
lastConnectTime: 0,
|
|
1156
|
-
reconnectAttempts: 0,
|
|
1157
|
-
connected: false,
|
|
1158
|
-
reconnecting: false
|
|
1159
|
-
};
|
|
386
|
+
isConnectedToNotifications() {
|
|
387
|
+
return this.notificationsClient.isConnected();
|
|
1160
388
|
}
|
|
1161
389
|
/**
|
|
1162
|
-
*
|
|
1163
|
-
* @
|
|
1164
|
-
* @returns {boolean} Успешность установки
|
|
390
|
+
* Получает ID активной сессии рассуждения
|
|
391
|
+
* @returns {string | null} ID активной сессии рассуждения или null
|
|
1165
392
|
*/
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
this.logger('error', 'Попытка установить пустой reasoningId');
|
|
1169
|
-
return false;
|
|
1170
|
-
}
|
|
1171
|
-
this.activeReasoningId = reasoningId;
|
|
1172
|
-
this.logger('info', `Установлен активный reasoningId: ${reasoningId}`);
|
|
1173
|
-
// Если мы уже подключены к пространству имен рассуждений, проверяем, нужно ли присоединиться
|
|
1174
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
1175
|
-
if (client && client.isConnected()) {
|
|
1176
|
-
// Пробуем присоединиться к рассуждению асинхронно, но не ждем результата
|
|
1177
|
-
this.logger('debug', `Автоматическое присоединение к рассуждению: ${reasoningId}`);
|
|
1178
|
-
client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1179
|
-
reasoningId,
|
|
1180
|
-
token: this.options.apiKey
|
|
1181
|
-
}, 10000).catch(err => {
|
|
1182
|
-
this.logger('warn', `Не удалось автоматически присоединиться к рассуждению: ${err.message}`);
|
|
1183
|
-
});
|
|
1184
|
-
}
|
|
1185
|
-
return true;
|
|
393
|
+
getActiveReasoningId() {
|
|
394
|
+
return this.reasoningClient.getActiveReasoningId();
|
|
1186
395
|
}
|
|
1187
396
|
/**
|
|
1188
|
-
*
|
|
1189
|
-
* @
|
|
1190
|
-
* @returns {boolean} Успешность установки
|
|
397
|
+
* Получает ID активного проекта
|
|
398
|
+
* @returns {string | null} ID активного проекта или null
|
|
1191
399
|
*/
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
this.logger('error', 'Попытка установить пустой projectId');
|
|
1195
|
-
return false;
|
|
1196
|
-
}
|
|
1197
|
-
this.activeProjectId = projectId;
|
|
1198
|
-
this.logger('info', `Установлен активный projectId: ${projectId}`);
|
|
1199
|
-
return true;
|
|
400
|
+
getActiveProjectId() {
|
|
401
|
+
return this.indexingClient.getActiveProjectId();
|
|
1200
402
|
}
|
|
1201
403
|
/**
|
|
1202
|
-
*
|
|
1203
|
-
* @param {
|
|
1204
|
-
* @param {
|
|
1205
|
-
* @param {
|
|
1206
|
-
* @returns {
|
|
404
|
+
* Отправляет сообщение в пространство имен
|
|
405
|
+
* @param {WebSocketNamespace} namespace Пространство имен
|
|
406
|
+
* @param {string} eventType Тип события
|
|
407
|
+
* @param {any} [data] Данные сообщения
|
|
408
|
+
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1207
409
|
*/
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
this.
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
this.logger('error', 'Не удалось создать новое рассуждение', error);
|
|
1221
|
-
return false;
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
// Отключаемся от предыдущего рассуждения, если оно отличается
|
|
1225
|
-
if (this.activeReasoningId && this.activeReasoningId !== reasoningId) {
|
|
1226
|
-
this.logger('debug', `Отписываемся от предыдущего рассуждения: ${this.activeReasoningId}`);
|
|
1227
|
-
this.unsubscribeFromThinking(this.activeReasoningId);
|
|
1228
|
-
}
|
|
1229
|
-
this.activeReasoningId = reasoningId;
|
|
1230
|
-
this.logger('info', `Установлен активный reasoningId: ${reasoningId}`);
|
|
1231
|
-
// Если соединение уже установлено, присоединяемся к рассуждению
|
|
1232
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
1233
|
-
if (client && client.isConnected()) {
|
|
1234
|
-
try {
|
|
1235
|
-
if (waitForJoin) {
|
|
1236
|
-
this.logger('debug', `Ожидание присоединения к рассуждению: ${reasoningId}`);
|
|
1237
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1238
|
-
reasoningId,
|
|
1239
|
-
token: this.options.apiKey
|
|
1240
|
-
}, 10000);
|
|
1241
|
-
if (joinResult.success === true) {
|
|
1242
|
-
this.logger('info', `Успешно присоединились к рассуждению: ${reasoningId}`);
|
|
1243
|
-
return true;
|
|
1244
|
-
}
|
|
1245
|
-
else {
|
|
1246
|
-
this.logger('warn', `Не удалось присоединиться к рассуждению: ${reasoningId}`, joinResult.error);
|
|
1247
|
-
return false;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
else {
|
|
1251
|
-
// Асинхронное присоединение
|
|
1252
|
-
this.logger('debug', `Асинхронное присоединение к рассуждению: ${reasoningId}`);
|
|
1253
|
-
client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1254
|
-
reasoningId,
|
|
1255
|
-
token: this.options.apiKey
|
|
1256
|
-
}, 10000).then(result => {
|
|
1257
|
-
if (result.success === true) {
|
|
1258
|
-
this.logger('info', `Успешно присоединились к рассуждению: ${reasoningId}`);
|
|
1259
|
-
}
|
|
1260
|
-
else {
|
|
1261
|
-
this.logger('warn', `Не удалось присоединиться к рассуждению: ${reasoningId}`, result.error);
|
|
1262
|
-
}
|
|
1263
|
-
}).catch(err => {
|
|
1264
|
-
this.logger('warn', `Ошибка при присоединении к рассуждению: ${reasoningId}`, err);
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
catch (error) {
|
|
1269
|
-
this.logger('error', `Ошибка при присоединении к рассуждению: ${reasoningId}`, error);
|
|
1270
|
-
if (waitForJoin)
|
|
1271
|
-
return false;
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
else if (waitForJoin) {
|
|
1275
|
-
// Если ждем присоединения, но соединение отсутствует
|
|
1276
|
-
this.logger('warn', `Нет активного соединения с сервером для присоединения к рассуждению: ${reasoningId}`);
|
|
1277
|
-
return false;
|
|
410
|
+
send(namespace, eventType, data) {
|
|
411
|
+
switch (namespace) {
|
|
412
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
413
|
+
return this.reasoningClient.send(eventType, data);
|
|
414
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
415
|
+
return this.indexingClient.send(eventType, data);
|
|
416
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
417
|
+
return this.dependenciesClient.send(eventType, data);
|
|
418
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
419
|
+
return this.notificationsClient.send(eventType, data);
|
|
420
|
+
default:
|
|
421
|
+
throw new Error(`Неизвестное пространство имен ${namespace}`);
|
|
1278
422
|
}
|
|
1279
|
-
return true;
|
|
1280
423
|
}
|
|
1281
424
|
/**
|
|
1282
|
-
*
|
|
1283
|
-
* @
|
|
1284
|
-
* @
|
|
425
|
+
* Отправляет сообщение в активную сессию рассуждения
|
|
426
|
+
* @param {string} eventType Тип события
|
|
427
|
+
* @param {any} [data] Данные сообщения
|
|
428
|
+
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1285
429
|
*/
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
if (!this.isConnectedToReasoning()) {
|
|
1289
|
-
this.logger('debug', 'Подключение к пространству имен рассуждений для создания нового рассуждения');
|
|
1290
|
-
const connected = await this.connectToReasoning();
|
|
1291
|
-
if (!connected) {
|
|
1292
|
-
throw new Error('Не удалось подключиться к пространству имен рассуждений');
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
1296
|
-
if (!client) {
|
|
1297
|
-
throw new Error('Не удалось получить клиент для пространства имен рассуждений');
|
|
1298
|
-
}
|
|
1299
|
-
this.logger('debug', 'Отправка запроса на создание нового рассуждения');
|
|
1300
|
-
const result = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.CREATE_REASONING, {
|
|
1301
|
-
token: this.options.apiKey
|
|
1302
|
-
}, 10000);
|
|
1303
|
-
if (!result.reasoningId) {
|
|
1304
|
-
throw new Error(`Сервер не вернул ID рассуждения: ${JSON.stringify(result)}`);
|
|
1305
|
-
}
|
|
1306
|
-
return result.reasoningId;
|
|
430
|
+
sendToReasoning(eventType, data) {
|
|
431
|
+
return this.reasoningClient.send(eventType, data);
|
|
1307
432
|
}
|
|
1308
433
|
/**
|
|
1309
|
-
*
|
|
1310
|
-
* @param {string}
|
|
1311
|
-
* @
|
|
434
|
+
* Отправляет сообщение в активную сессию индексации
|
|
435
|
+
* @param {string} eventType Тип события
|
|
436
|
+
* @param {any} [data] Данные сообщения
|
|
437
|
+
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1312
438
|
*/
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
return false;
|
|
1316
|
-
}
|
|
1317
|
-
// Подключаемся, если еще не подключены
|
|
1318
|
-
if (!this.isConnectedToReasoning()) {
|
|
1319
|
-
const connected = await this.connectToReasoning();
|
|
1320
|
-
if (!connected) {
|
|
1321
|
-
this.logger('warn', 'Не удалось подключиться к пространству имен рассуждений для проверки существования');
|
|
1322
|
-
return false;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
1326
|
-
if (!client) {
|
|
1327
|
-
this.logger('warn', 'Не удалось получить клиент для пространства имен рассуждений');
|
|
1328
|
-
return false;
|
|
1329
|
-
}
|
|
1330
|
-
try {
|
|
1331
|
-
this.logger('debug', `Проверка существования рассуждения: ${reasoningId}`);
|
|
1332
|
-
// Используем более правильный подход для проверки существования сессии
|
|
1333
|
-
// Пытаемся присоединиться, и если успешно - значит сессия существует
|
|
1334
|
-
const result = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1335
|
-
reasoningId,
|
|
1336
|
-
token: this.options.apiKey
|
|
1337
|
-
}, 10000);
|
|
1338
|
-
return result.success === true;
|
|
1339
|
-
}
|
|
1340
|
-
catch (error) {
|
|
1341
|
-
this.logger('warn', `Ошибка при проверке существования рассуждения: ${reasoningId}`, error);
|
|
1342
|
-
return false;
|
|
1343
|
-
}
|
|
439
|
+
sendToIndexing(eventType, data) {
|
|
440
|
+
return this.indexingClient.send(eventType, data);
|
|
1344
441
|
}
|
|
1345
442
|
/**
|
|
1346
|
-
*
|
|
1347
|
-
* @param
|
|
1348
|
-
* @param
|
|
1349
|
-
* @returns
|
|
443
|
+
* Отправляет сообщение в уведомления
|
|
444
|
+
* @param {string} eventType Тип события
|
|
445
|
+
* @param {any} [data] Данные сообщения
|
|
446
|
+
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1350
447
|
*/
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
// Значения опций по умолчанию
|
|
1354
|
-
const { autoJoin = true, createIfNotExists = false, checkExistence = false, saveSession = this.options.enableSessionPersistence !== false } = options;
|
|
1355
|
-
this.logger('info', 'Подключение к пространству имен рассуждений', {
|
|
1356
|
-
reasoningId,
|
|
1357
|
-
options: { autoJoin, createIfNotExists, checkExistence, saveSession }
|
|
1358
|
-
});
|
|
1359
|
-
// Если указан ID рассуждения, обрабатываем его
|
|
1360
|
-
if (reasoningId) {
|
|
1361
|
-
// Если нужно проверить существование
|
|
1362
|
-
if (checkExistence) {
|
|
1363
|
-
const client = this.clients.get(WebSocketNamespace.REASONING);
|
|
1364
|
-
// Если уже подключены, проверяем существование
|
|
1365
|
-
if (client && client.isConnected()) {
|
|
1366
|
-
const exists = await this.checkReasoningExists(reasoningId);
|
|
1367
|
-
if (!exists) {
|
|
1368
|
-
if (createIfNotExists) {
|
|
1369
|
-
this.logger('info', `Рассуждение ${reasoningId} не существует, создаем новое`);
|
|
1370
|
-
reasoningId = await this.createNewReasoning();
|
|
1371
|
-
}
|
|
1372
|
-
else {
|
|
1373
|
-
this.logger('warn', `Рассуждение ${reasoningId} не существует`);
|
|
1374
|
-
return false;
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
// Устанавливаем ID активного рассуждения
|
|
1380
|
-
this.activeReasoningId = reasoningId;
|
|
1381
|
-
}
|
|
1382
|
-
else if (createIfNotExists) {
|
|
1383
|
-
// Если нет ID, но нужно создать, создаем новое рассуждение
|
|
1384
|
-
this.logger('info', 'Создание нового рассуждения');
|
|
1385
|
-
try {
|
|
1386
|
-
// Получаем параметры авторизации для пространства имен рассуждений
|
|
1387
|
-
const authParams = (0, reasoning_auth_helper_js_1.createReasoningConnectionParams)(this.options.apiKey, undefined, this.getSessionToken(WebSocketNamespace.REASONING));
|
|
1388
|
-
// Сначала подключаемся к пространству имен с нужными параметрами
|
|
1389
|
-
const client = await this.connect(WebSocketNamespace.REASONING, authParams);
|
|
1390
|
-
// Затем создаем новое рассуждение
|
|
1391
|
-
const newReasoningId = await this.createNewReasoning();
|
|
1392
|
-
this.activeReasoningId = newReasoningId;
|
|
1393
|
-
this.logger('info', `Создано новое рассуждение: ${newReasoningId}`);
|
|
1394
|
-
}
|
|
1395
|
-
catch (error) {
|
|
1396
|
-
this.logger('error', 'Ошибка при создании нового рассуждения', error);
|
|
1397
|
-
return false;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
// Получаем параметры авторизации для пространства имен рассуждений
|
|
1401
|
-
const sessionToken = this.getSessionToken(WebSocketNamespace.REASONING);
|
|
1402
|
-
const authParams = (0, reasoning_auth_helper_js_1.createReasoningConnectionParams)(this.options.apiKey, this.activeReasoningId, sessionToken);
|
|
1403
|
-
// Подключаемся к пространству имен рассуждений с параметрами аутентификации
|
|
1404
|
-
const client = await this.connect(WebSocketNamespace.REASONING, authParams);
|
|
1405
|
-
// Аутентифицируемся с увеличенным таймаутом
|
|
1406
|
-
try {
|
|
1407
|
-
const authResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.AUTHENTICATE, {
|
|
1408
|
-
token: this.options.apiKey,
|
|
1409
|
-
reasoningId: this.activeReasoningId
|
|
1410
|
-
}, 10000);
|
|
1411
|
-
this.logger('debug', 'Результат аутентификации в namespace рассуждений', authResult);
|
|
1412
|
-
// Если сервер вернул токен сессии и нужно его сохранить
|
|
1413
|
-
if (saveSession && authResult.sessionToken) {
|
|
1414
|
-
this.saveSessionToken(WebSocketNamespace.REASONING, authResult.sessionToken);
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
catch (error) {
|
|
1418
|
-
this.logger('error', 'Ошибка аутентификации в namespace рассуждений', error);
|
|
1419
|
-
return false;
|
|
1420
|
-
}
|
|
1421
|
-
// Если у нас есть ID рассуждения и включено автоматическое присоединение
|
|
1422
|
-
if (this.activeReasoningId && autoJoin) {
|
|
1423
|
-
try {
|
|
1424
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1425
|
-
reasoningId: this.activeReasoningId,
|
|
1426
|
-
token: this.options.apiKey
|
|
1427
|
-
}, 10000);
|
|
1428
|
-
this.logger('debug', 'Результат присоединения к рассуждению', joinResult);
|
|
1429
|
-
if (joinResult.success !== true) {
|
|
1430
|
-
this.logger('warn', `Не удалось присоединиться к рассуждению: ${this.activeReasoningId}`, joinResult.error);
|
|
1431
|
-
return false;
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
catch (error) {
|
|
1435
|
-
this.logger('error', 'Ошибка присоединения к рассуждению', error);
|
|
1436
|
-
return false;
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
// Включаем автоматический ping/pong, если настроено
|
|
1440
|
-
if (this.options.enableAutoPing !== false) {
|
|
1441
|
-
this.enablePingPong(this.options.pingInterval, this.options.pingTimeoutThreshold);
|
|
1442
|
-
}
|
|
1443
|
-
return true;
|
|
1444
|
-
}
|
|
1445
|
-
catch (error) {
|
|
1446
|
-
this.logger('error', 'Ошибка подключения к пространству имен рассуждений', error);
|
|
1447
|
-
return false;
|
|
1448
|
-
}
|
|
448
|
+
sendToNotifications(eventType, data) {
|
|
449
|
+
return this.notificationsClient.send(eventType, data);
|
|
1449
450
|
}
|
|
1450
451
|
/**
|
|
1451
|
-
*
|
|
1452
|
-
* @param {string}
|
|
1453
|
-
* @
|
|
452
|
+
* Добавляет обработчик события для пространства имен
|
|
453
|
+
* @param {string} eventType Тип события
|
|
454
|
+
* @param {Function} handler Обработчик события
|
|
455
|
+
* @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, добавляется ко всем активным)
|
|
1454
456
|
*/
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
try {
|
|
1472
|
-
// Используем событие GET_REASONING_STATUS для получения статуса
|
|
1473
|
-
// Если сервер не поддерживает это событие, используем более простую проверку
|
|
1474
|
-
try {
|
|
1475
|
-
const status = await client.emitWithAck('get_reasoning_status', {
|
|
1476
|
-
reasoningId: targetId,
|
|
1477
|
-
token: this.options.apiKey
|
|
1478
|
-
}, 10000);
|
|
1479
|
-
return {
|
|
1480
|
-
exists: status.exists === true,
|
|
1481
|
-
isActive: status.isActive === true,
|
|
1482
|
-
metadata: status.metadata || {}
|
|
1483
|
-
};
|
|
1484
|
-
}
|
|
1485
|
-
catch (e) {
|
|
1486
|
-
// Если произошла ошибка (скорее всего, сервер не поддерживает этот метод),
|
|
1487
|
-
// используем проверку через JOIN_REASONING
|
|
1488
|
-
const result = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1489
|
-
reasoningId: targetId,
|
|
1490
|
-
token: this.options.apiKey
|
|
1491
|
-
}, 10000);
|
|
1492
|
-
return {
|
|
1493
|
-
exists: result.success === true,
|
|
1494
|
-
isActive: result.success === true,
|
|
1495
|
-
metadata: result.data
|
|
1496
|
-
};
|
|
457
|
+
on(eventType, handler, namespace) {
|
|
458
|
+
if (namespace) {
|
|
459
|
+
// Если указано пространство имен, добавляем обработчик только к нему
|
|
460
|
+
switch (namespace) {
|
|
461
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
462
|
+
this.reasoningClient.on(eventType, handler);
|
|
463
|
+
break;
|
|
464
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
465
|
+
this.indexingClient.on(eventType, handler);
|
|
466
|
+
break;
|
|
467
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
468
|
+
this.dependenciesClient.on(eventType, handler);
|
|
469
|
+
break;
|
|
470
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
471
|
+
this.notificationsClient.on(eventType, handler);
|
|
472
|
+
break;
|
|
1497
473
|
}
|
|
1498
474
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
475
|
+
else {
|
|
476
|
+
// Если пространство имен не указано, добавляем обработчик ко всем активным
|
|
477
|
+
this.reasoningClient.on(eventType, handler);
|
|
478
|
+
this.indexingClient.on(eventType, handler);
|
|
479
|
+
this.dependenciesClient.on(eventType, handler);
|
|
480
|
+
this.notificationsClient.on(eventType, handler);
|
|
1502
481
|
}
|
|
1503
482
|
}
|
|
1504
483
|
/**
|
|
1505
|
-
*
|
|
1506
|
-
* @param {string}
|
|
1507
|
-
* @param {
|
|
1508
|
-
* @
|
|
484
|
+
* Удаляет обработчик события для пространства имен
|
|
485
|
+
* @param {string} eventType Тип события
|
|
486
|
+
* @param {Function} [handler] Обработчик события (если не указан, удаляются все обработчики)
|
|
487
|
+
* @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, удаляется из всех активных)
|
|
1509
488
|
*/
|
|
1510
|
-
|
|
1511
|
-
if (
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
489
|
+
off(eventType, handler, namespace) {
|
|
490
|
+
if (namespace) {
|
|
491
|
+
// Если указано пространство имен, удаляем обработчик только из него
|
|
492
|
+
switch (namespace) {
|
|
493
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
494
|
+
this.reasoningClient.off(eventType, handler);
|
|
495
|
+
break;
|
|
496
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
497
|
+
this.indexingClient.off(eventType, handler);
|
|
498
|
+
break;
|
|
499
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
500
|
+
this.dependenciesClient.off(eventType, handler);
|
|
501
|
+
break;
|
|
502
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
503
|
+
this.notificationsClient.off(eventType, handler);
|
|
504
|
+
break;
|
|
1525
505
|
}
|
|
1526
|
-
return true; // connectToReasoning уже выполнил join
|
|
1527
506
|
}
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
this.
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
try {
|
|
1535
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1536
|
-
reasoningId,
|
|
1537
|
-
token: this.options.apiKey
|
|
1538
|
-
}, 10000);
|
|
1539
|
-
this.logger('debug', `Результат присоединения к рассуждению ${reasoningId}`, joinResult);
|
|
1540
|
-
return joinResult.success === true;
|
|
1541
|
-
}
|
|
1542
|
-
catch (error) {
|
|
1543
|
-
this.logger('error', `Ошибка при присоединении к рассуждению ${reasoningId}`, error);
|
|
1544
|
-
return false;
|
|
507
|
+
else {
|
|
508
|
+
// Если пространство имен не указано, удаляем обработчик из всех активных
|
|
509
|
+
this.reasoningClient.off(eventType, handler);
|
|
510
|
+
this.indexingClient.off(eventType, handler);
|
|
511
|
+
this.dependenciesClient.off(eventType, handler);
|
|
512
|
+
this.notificationsClient.off(eventType, handler);
|
|
1545
513
|
}
|
|
1546
514
|
}
|
|
1547
515
|
/**
|
|
1548
|
-
*
|
|
1549
|
-
* @param
|
|
1550
|
-
* @
|
|
1551
|
-
* @returns Promise с результатом подключения
|
|
516
|
+
* Получает ID сокета для указанного пространства имен
|
|
517
|
+
* @param {WebSocketNamespace} [namespace=WebSocketNamespace.REASONING] Пространство имен
|
|
518
|
+
* @returns {string|null} ID сокета или null, если соединение не установлено
|
|
1552
519
|
*/
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
// Если нужно проверить существование рассуждения
|
|
1566
|
-
if (checkExistence && this.activeReasoningId) {
|
|
1567
|
-
try {
|
|
1568
|
-
const status = await this.getReasoningStatus(this.activeReasoningId);
|
|
1569
|
-
// Если рассуждение не существует, можем создать его
|
|
1570
|
-
if (!status.exists && createIfNotExists) {
|
|
1571
|
-
const created = await this.createNewReasoning();
|
|
1572
|
-
if (!created) {
|
|
1573
|
-
this.logger('warn', `Не удалось создать рассуждение ${this.activeReasoningId}`);
|
|
1574
|
-
return false;
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
else if (!status.exists) {
|
|
1578
|
-
this.logger('warn', `Рассуждение ${this.activeReasoningId} не существует`);
|
|
1579
|
-
return false;
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
catch (error) {
|
|
1583
|
-
this.logger('warn', 'Ошибка при проверке существования рассуждения', error);
|
|
1584
|
-
// Продолжаем, так как ошибка может быть связана с отсутствием подключения
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
// Получаем сохраненный токен сессии, если есть
|
|
1588
|
-
const sessionToken = this.getSessionToken(WebSocketNamespace.REASONING);
|
|
1589
|
-
// Получаем параметры для аутентификации
|
|
1590
|
-
const authParams = (0, reasoning_auth_helper_js_1.createReasoningConnectionParams)(this.options.apiKey, this.activeReasoningId, sessionToken);
|
|
1591
|
-
// Подключаемся к пространству имен рассуждений
|
|
1592
|
-
const client = await this.connect(WebSocketNamespace.REASONING, authParams);
|
|
1593
|
-
// Аутентифицируемся с увеличенным таймаутом
|
|
1594
|
-
try {
|
|
1595
|
-
const authResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.AUTHENTICATE, {
|
|
1596
|
-
token: this.options.apiKey,
|
|
1597
|
-
reasoningId: this.activeReasoningId
|
|
1598
|
-
}, 10000);
|
|
1599
|
-
this.logger('debug', 'Результат аутентификации в namespace рассуждений', authResult);
|
|
1600
|
-
// Если сервер вернул токен сессии и нужно его сохранить
|
|
1601
|
-
if (saveSession && authResult.sessionToken) {
|
|
1602
|
-
this.saveSessionToken(WebSocketNamespace.REASONING, authResult.sessionToken);
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
catch (error) {
|
|
1606
|
-
this.logger('error', 'Ошибка аутентификации в namespace рассуждений', error);
|
|
1607
|
-
return false;
|
|
1608
|
-
}
|
|
1609
|
-
// Если у нас есть ID рассуждения и включено автоматическое присоединение
|
|
1610
|
-
if (this.activeReasoningId && autoJoin) {
|
|
1611
|
-
try {
|
|
1612
|
-
const joinResult = await client.emitWithAck(websocket_events_constants_js_1.WebSocketEvents.JOIN_REASONING, {
|
|
1613
|
-
reasoningId: this.activeReasoningId,
|
|
1614
|
-
token: this.options.apiKey
|
|
1615
|
-
}, 10000);
|
|
1616
|
-
this.logger('debug', 'Результат присоединения к рассуждению', joinResult);
|
|
1617
|
-
if (joinResult.success !== true) {
|
|
1618
|
-
this.logger('warn', `Не удалось присоединиться к рассуждению: ${this.activeReasoningId}`, joinResult.error);
|
|
1619
|
-
return false;
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
catch (error) {
|
|
1623
|
-
this.logger('error', 'Ошибка присоединения к рассуждению', error);
|
|
1624
|
-
return false;
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
// Включаем автоматический ping/pong, если настроено
|
|
1628
|
-
if (this.options.enableAutoPing !== false) {
|
|
1629
|
-
this.enablePingPong(this.options.pingInterval, this.options.pingTimeoutThreshold);
|
|
1630
|
-
}
|
|
1631
|
-
return true;
|
|
1632
|
-
}
|
|
1633
|
-
catch (error) {
|
|
1634
|
-
this.logger('error', 'Ошибка подключения к пространству имен рассуждений', error);
|
|
1635
|
-
return false;
|
|
520
|
+
getSocketId(namespace = websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING) {
|
|
521
|
+
switch (namespace) {
|
|
522
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING:
|
|
523
|
+
return this.reasoningClient.getSocketId();
|
|
524
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING:
|
|
525
|
+
return this.indexingClient.getSocketId();
|
|
526
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES:
|
|
527
|
+
return this.dependenciesClient.getSocketId();
|
|
528
|
+
case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT:
|
|
529
|
+
return this.notificationsClient.getSocketId();
|
|
530
|
+
default:
|
|
531
|
+
return null;
|
|
1636
532
|
}
|
|
1637
533
|
}
|
|
1638
534
|
/**
|
|
1639
|
-
*
|
|
1640
|
-
* @
|
|
1641
|
-
* @returns {WebSocketNamespace} Соответствующее перечисление
|
|
1642
|
-
* @private
|
|
535
|
+
* Получает диагностическую информацию о соединениях
|
|
536
|
+
* @returns {object} Диагностическая информация
|
|
1643
537
|
*/
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
return namespace;
|
|
1647
|
-
}
|
|
1648
|
-
// Сопоставляем строковые значения с перечислением
|
|
1649
|
-
if (namespace === 'indexing' || namespace === '/indexing') {
|
|
1650
|
-
return WebSocketNamespace.INDEXING;
|
|
1651
|
-
}
|
|
1652
|
-
else if (namespace === 'reasoning' || namespace === '/reasoning') {
|
|
1653
|
-
return WebSocketNamespace.REASONING;
|
|
1654
|
-
}
|
|
1655
|
-
else if (namespace === 'dependencies' || namespace === '/dependencies') {
|
|
1656
|
-
return WebSocketNamespace.DEPENDENCIES;
|
|
1657
|
-
}
|
|
1658
|
-
else {
|
|
1659
|
-
return WebSocketNamespace.DEFAULT;
|
|
1660
|
-
}
|
|
538
|
+
getDiagnostics() {
|
|
539
|
+
return this.diagnosticsService.getDiagnostics();
|
|
1661
540
|
}
|
|
1662
541
|
}
|
|
1663
542
|
exports.CodeSolverWebSocketClient = CodeSolverWebSocketClient;
|