solver-sdk 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -75
- package/dist/esm/index.js +21 -1829
- package/dist/esm/index.js.map +1 -1
- package/package.json +21 -10
- package/dist/esm/types/api/agents-api.d.ts +0 -141
- package/dist/esm/types/api/agents-api.d.ts.map +0 -1
- package/dist/esm/types/api/code-modification-api.d.ts +0 -104
- package/dist/esm/types/api/code-modification-api.d.ts.map +0 -1
- package/dist/esm/types/api/context-api.d.ts +0 -86
- package/dist/esm/types/api/context-api.d.ts.map +0 -1
- package/dist/esm/types/api/projects-api.d.ts +0 -131
- package/dist/esm/types/api/projects-api.d.ts.map +0 -1
- package/dist/esm/types/api/reasoning-api.d.ts +0 -188
- package/dist/esm/types/api/reasoning-api.d.ts.map +0 -1
- package/dist/esm/types/api/search-api.d.ts +0 -92
- package/dist/esm/types/api/search-api.d.ts.map +0 -1
- package/dist/esm/types/code-solver-sdk.d.ts +0 -145
- package/dist/esm/types/code-solver-sdk.d.ts.map +0 -1
- package/dist/esm/types/index.d.ts +0 -81
- package/dist/esm/types/index.d.ts.map +0 -1
- package/dist/esm/types/interfaces/http-client.d.ts +0 -110
- package/dist/esm/types/interfaces/http-client.d.ts.map +0 -1
- package/dist/esm/types/interfaces/sdk-options.d.ts +0 -34
- package/dist/esm/types/interfaces/sdk-options.d.ts.map +0 -1
- package/dist/esm/types/models/types.d.ts +0 -139
- package/dist/esm/types/models/types.d.ts.map +0 -1
- package/dist/esm/types/utils/code-solver-websocket-client.d.ts +0 -138
- package/dist/esm/types/utils/code-solver-websocket-client.d.ts.map +0 -1
- package/dist/esm/types/utils/http-client.d.ts +0 -85
- package/dist/esm/types/utils/http-client.d.ts.map +0 -1
- package/dist/esm/types/utils/indexing-websocket-client.d.ts +0 -123
- package/dist/esm/types/utils/indexing-websocket-client.d.ts.map +0 -1
- package/dist/esm/types/utils/sse-client.d.ts +0 -92
- package/dist/esm/types/utils/sse-client.d.ts.map +0 -1
- package/dist/esm/types/utils/websocket-client.d.ts +0 -118
- package/dist/esm/types/utils/websocket-client.d.ts.map +0 -1
- package/dist/index.d.ts +0 -1665
- package/dist/umd/code-solver-sdk.js +0 -1915
- package/dist/umd/code-solver-sdk.js.map +0 -1
- package/dist/umd/code-solver-sdk.min.js +0 -2
- package/dist/umd/code-solver-sdk.min.js.map +0 -1
- package/dist/umd/types/api/agents-api.d.ts +0 -141
- package/dist/umd/types/api/agents-api.d.ts.map +0 -1
- package/dist/umd/types/api/code-modification-api.d.ts +0 -104
- package/dist/umd/types/api/code-modification-api.d.ts.map +0 -1
- package/dist/umd/types/api/context-api.d.ts +0 -86
- package/dist/umd/types/api/context-api.d.ts.map +0 -1
- package/dist/umd/types/api/projects-api.d.ts +0 -131
- package/dist/umd/types/api/projects-api.d.ts.map +0 -1
- package/dist/umd/types/api/reasoning-api.d.ts +0 -188
- package/dist/umd/types/api/reasoning-api.d.ts.map +0 -1
- package/dist/umd/types/api/search-api.d.ts +0 -92
- package/dist/umd/types/api/search-api.d.ts.map +0 -1
- package/dist/umd/types/code-solver-sdk.d.ts +0 -145
- package/dist/umd/types/code-solver-sdk.d.ts.map +0 -1
- package/dist/umd/types/index.d.ts +0 -81
- package/dist/umd/types/index.d.ts.map +0 -1
- package/dist/umd/types/interfaces/http-client.d.ts +0 -110
- package/dist/umd/types/interfaces/http-client.d.ts.map +0 -1
- package/dist/umd/types/interfaces/sdk-options.d.ts +0 -34
- package/dist/umd/types/interfaces/sdk-options.d.ts.map +0 -1
- package/dist/umd/types/models/types.d.ts +0 -139
- package/dist/umd/types/models/types.d.ts.map +0 -1
- package/dist/umd/types/utils/code-solver-websocket-client.d.ts +0 -138
- package/dist/umd/types/utils/code-solver-websocket-client.d.ts.map +0 -1
- package/dist/umd/types/utils/http-client.d.ts +0 -85
- package/dist/umd/types/utils/http-client.d.ts.map +0 -1
- package/dist/umd/types/utils/indexing-websocket-client.d.ts +0 -123
- package/dist/umd/types/utils/indexing-websocket-client.d.ts.map +0 -1
- package/dist/umd/types/utils/sse-client.d.ts +0 -92
- package/dist/umd/types/utils/sse-client.d.ts.map +0 -1
- package/dist/umd/types/utils/websocket-client.d.ts +0 -118
- package/dist/umd/types/utils/websocket-client.d.ts.map +0 -1
package/dist/esm/index.js
CHANGED
|
@@ -1,1830 +1,24 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { EventSourcePolyfill } from 'event-source-polyfill';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Определение типа среды выполнения
|
|
6
|
-
* @returns 'browser' | 'node'
|
|
7
|
-
*/
|
|
8
|
-
function getEnvironment$1() {
|
|
9
|
-
return (typeof window !== 'undefined' && typeof window.document !== 'undefined')
|
|
10
|
-
? 'browser'
|
|
11
|
-
: 'node';
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* HTTP клиент для выполнения запросов к API
|
|
15
|
-
*
|
|
16
|
-
* Предоставляет методы для работы с REST API, включая обработку ошибок,
|
|
17
|
-
* повторные попытки и таймауты.
|
|
18
|
-
*/
|
|
19
|
-
class HttpClient {
|
|
20
|
-
/**
|
|
21
|
-
* Создает новый HTTP клиент
|
|
22
|
-
* @param {string} baseURL Базовый URL для запросов
|
|
23
|
-
* @param {HttpClientOptions} [options] Опции для HTTP клиента
|
|
24
|
-
*/
|
|
25
|
-
constructor(baseURL, options = {}) {
|
|
26
|
-
this.baseURL = baseURL;
|
|
27
|
-
this.options = {
|
|
28
|
-
headers: {
|
|
29
|
-
'Content-Type': 'application/json',
|
|
30
|
-
'Accept': 'application/json',
|
|
31
|
-
...(options.headers || {})
|
|
32
|
-
},
|
|
33
|
-
timeout: options.timeout || 30000,
|
|
34
|
-
retry: options.retry || {
|
|
35
|
-
maxRetries: 3,
|
|
36
|
-
retryDelay: 1000,
|
|
37
|
-
maxRetryDelay: 10000,
|
|
38
|
-
retryStatusCodes: [408, 429, 500, 502, 503, 504]
|
|
39
|
-
},
|
|
40
|
-
httpsAgent: options.httpsAgent
|
|
41
|
-
};
|
|
42
|
-
this.environment = getEnvironment$1();
|
|
43
|
-
// Создаем Axios инстанс с базовыми настройками
|
|
44
|
-
this.axiosInstance = axios.create({
|
|
45
|
-
baseURL: this.baseURL,
|
|
46
|
-
timeout: this.options.timeout,
|
|
47
|
-
headers: this.options.headers,
|
|
48
|
-
...(this.environment === 'node' && this.options.httpsAgent ? { httpsAgent: this.options.httpsAgent } : {})
|
|
49
|
-
});
|
|
50
|
-
// Добавляем интерцептор для обработки ошибок и повторных попыток
|
|
51
|
-
this.setupInterceptors();
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Настраивает интерцепторы Axios
|
|
55
|
-
*/
|
|
56
|
-
setupInterceptors() {
|
|
57
|
-
// Интерцептор для ответов
|
|
58
|
-
this.axiosInstance.interceptors.response.use((response) => response.data, async (error) => {
|
|
59
|
-
const { config, response } = error;
|
|
60
|
-
// Если нет конфига запроса или это уже повторный запрос, или skipRetry установлен, возвращаем ошибку
|
|
61
|
-
if (!config || config._retryCount || config.skipRetry) {
|
|
62
|
-
return Promise.reject(error);
|
|
63
|
-
}
|
|
64
|
-
config._retryCount = config._retryCount || 0;
|
|
65
|
-
const retryConfig = this.options.retry;
|
|
66
|
-
// Проверяем, нужно ли делать повторную попытку для данного статуса
|
|
67
|
-
const shouldRetry = response &&
|
|
68
|
-
retryConfig.retryStatusCodes?.includes(response.status) &&
|
|
69
|
-
config._retryCount < (retryConfig.maxRetries || 3);
|
|
70
|
-
if (shouldRetry) {
|
|
71
|
-
config._retryCount += 1;
|
|
72
|
-
// Вычисляем время задержки перед повторной попыткой
|
|
73
|
-
const delay = Math.min((retryConfig.retryDelay || 1000) * Math.pow(2, config._retryCount - 1), retryConfig.maxRetryDelay || 10000);
|
|
74
|
-
// Ждем перед повторной попыткой
|
|
75
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
76
|
-
// Делаем повторную попытку
|
|
77
|
-
return this.axiosInstance(config);
|
|
78
|
-
}
|
|
79
|
-
// Если не нужно делать повторную попытку, возвращаем ошибку
|
|
80
|
-
return Promise.reject(error);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Выполняет HTTP запрос
|
|
85
|
-
* @param {RequestOptions} options Опции запроса
|
|
86
|
-
* @returns {Promise<T>} Ответ от API
|
|
87
|
-
*/
|
|
88
|
-
async request(options) {
|
|
89
|
-
const axiosConfig = {
|
|
90
|
-
url: options.url,
|
|
91
|
-
method: options.method,
|
|
92
|
-
data: options.data,
|
|
93
|
-
params: options.params,
|
|
94
|
-
headers: {
|
|
95
|
-
...this.options.headers,
|
|
96
|
-
...(options.headers || {})
|
|
97
|
-
},
|
|
98
|
-
timeout: options.timeout || this.options.timeout
|
|
99
|
-
};
|
|
100
|
-
// Если указано не делать повторные попытки, добавляем специальный флаг
|
|
101
|
-
if (options.noRetry) {
|
|
102
|
-
axiosConfig.skipRetry = true;
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
return await this.axiosInstance.request(axiosConfig);
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
throw this.handleError(error);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Выполняет GET запрос
|
|
113
|
-
* @param {string} url URL для запроса
|
|
114
|
-
* @param {Record<string, any>} [params] Query параметры
|
|
115
|
-
* @param {Record<string, string>} [headers] HTTP заголовки
|
|
116
|
-
* @returns {Promise<T>} Ответ от API
|
|
117
|
-
*/
|
|
118
|
-
async get(url, params, headers) {
|
|
119
|
-
return this.request({
|
|
120
|
-
url,
|
|
121
|
-
method: 'GET',
|
|
122
|
-
params,
|
|
123
|
-
headers
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Выполняет POST запрос
|
|
128
|
-
* @param {string} url URL для запроса
|
|
129
|
-
* @param {any} [data] Данные для отправки
|
|
130
|
-
* @param {Record<string, string>} [headers] HTTP заголовки
|
|
131
|
-
* @returns {Promise<T>} Ответ от API
|
|
132
|
-
*/
|
|
133
|
-
async post(url, data, headers) {
|
|
134
|
-
return this.request({
|
|
135
|
-
url,
|
|
136
|
-
method: 'POST',
|
|
137
|
-
data,
|
|
138
|
-
headers
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Выполняет PUT запрос
|
|
143
|
-
* @param {string} url URL для запроса
|
|
144
|
-
* @param {any} [data] Данные для отправки
|
|
145
|
-
* @param {Record<string, string>} [headers] HTTP заголовки
|
|
146
|
-
* @returns {Promise<T>} Ответ от API
|
|
147
|
-
*/
|
|
148
|
-
async put(url, data, headers) {
|
|
149
|
-
return this.request({
|
|
150
|
-
url,
|
|
151
|
-
method: 'PUT',
|
|
152
|
-
data,
|
|
153
|
-
headers
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Выполняет DELETE запрос
|
|
158
|
-
* @param {string} url URL для запроса
|
|
159
|
-
* @param {Record<string, any>} [params] Query параметры
|
|
160
|
-
* @param {Record<string, string>} [headers] HTTP заголовки
|
|
161
|
-
* @returns {Promise<T>} Ответ от API
|
|
162
|
-
*/
|
|
163
|
-
async delete(url, params, headers) {
|
|
164
|
-
return this.request({
|
|
165
|
-
url,
|
|
166
|
-
method: 'DELETE',
|
|
167
|
-
params,
|
|
168
|
-
headers
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Выполняет PATCH запрос
|
|
173
|
-
* @param {string} url URL для запроса
|
|
174
|
-
* @param {any} [data] Данные для отправки
|
|
175
|
-
* @param {Record<string, string>} [headers] HTTP заголовки
|
|
176
|
-
* @returns {Promise<T>} Ответ от API
|
|
177
|
-
*/
|
|
178
|
-
async patch(url, data, headers) {
|
|
179
|
-
return this.request({
|
|
180
|
-
url,
|
|
181
|
-
method: 'PATCH',
|
|
182
|
-
data,
|
|
183
|
-
headers
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Обрабатывает ошибки от Axios
|
|
188
|
-
* @param {any} error Ошибка от Axios
|
|
189
|
-
* @returns {Error} Обработанная ошибка
|
|
190
|
-
*/
|
|
191
|
-
handleError(error) {
|
|
192
|
-
let enhancedError;
|
|
193
|
-
if (error.response) {
|
|
194
|
-
// Ошибка от сервера с кодом ответа
|
|
195
|
-
const { status, data } = error.response;
|
|
196
|
-
const message = data?.message || data?.error || `HTTP ошибка ${status}`;
|
|
197
|
-
enhancedError = new Error(message);
|
|
198
|
-
enhancedError.status = status;
|
|
199
|
-
enhancedError.data = data;
|
|
200
|
-
enhancedError.isApiError = true;
|
|
201
|
-
}
|
|
202
|
-
else if (error.request) {
|
|
203
|
-
// Запрос был сделан, но ответ не получен
|
|
204
|
-
enhancedError = new Error('Нет ответа от сервера. Проверьте подключение к интернету.');
|
|
205
|
-
enhancedError.request = error.request;
|
|
206
|
-
enhancedError.isNetworkError = true;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
// Произошла ошибка при настройке запроса
|
|
210
|
-
enhancedError = new Error(error.message || 'Произошла неизвестная ошибка');
|
|
211
|
-
enhancedError.isUnknownError = true;
|
|
212
|
-
}
|
|
213
|
-
// Сохраняем оригинальную ошибку для отладки
|
|
214
|
-
enhancedError.originalError = error;
|
|
215
|
-
// Пытаемся обработать ошибку через глобальный обработчик
|
|
216
|
-
try {
|
|
217
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
218
|
-
const { CodeSolverSDK } = require('../code-solver-sdk.js');
|
|
219
|
-
if (typeof CodeSolverSDK.handleError === 'function') {
|
|
220
|
-
CodeSolverSDK.handleError(enhancedError);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
catch (e) {
|
|
224
|
-
// Игнорируем ошибки при импорте или вызове обработчика
|
|
225
|
-
}
|
|
226
|
-
return enhancedError;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* API для работы с проектами
|
|
232
|
-
*/
|
|
233
|
-
class ProjectsApi {
|
|
234
|
-
/**
|
|
235
|
-
* Создает новый экземпляр API для работы с проектами
|
|
236
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
237
|
-
*/
|
|
238
|
-
constructor(httpClient) {
|
|
239
|
-
this.httpClient = httpClient;
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Получает список всех проектов
|
|
243
|
-
* @returns {Promise<Project[]>} Список проектов
|
|
244
|
-
*/
|
|
245
|
-
async getAllProjects() {
|
|
246
|
-
return this.httpClient.get('/api/v1/projects');
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Получает проект по ID
|
|
250
|
-
* @param {string} projectId ID проекта
|
|
251
|
-
* @returns {Promise<Project>} Проект
|
|
252
|
-
*/
|
|
253
|
-
async getProject(projectId) {
|
|
254
|
-
return this.httpClient.get(`/api/v1/projects/${projectId}`);
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Создает новый проект
|
|
258
|
-
* @param {string} name Название проекта
|
|
259
|
-
* @param {string} path Путь к проекту
|
|
260
|
-
* @param {ProjectOptions} [options] Дополнительные опции проекта
|
|
261
|
-
* @returns {Promise<Project>} Созданный проект
|
|
262
|
-
*/
|
|
263
|
-
async createProject(name, path, options) {
|
|
264
|
-
return this.httpClient.post('/api/v1/projects', {
|
|
265
|
-
name,
|
|
266
|
-
path,
|
|
267
|
-
...options
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Обновляет проект
|
|
272
|
-
* @param {string} projectId ID проекта
|
|
273
|
-
* @param {Partial<ProjectUpdateData>} data Данные для обновления
|
|
274
|
-
* @returns {Promise<Project>} Обновленный проект
|
|
275
|
-
*/
|
|
276
|
-
async updateProject(projectId, data) {
|
|
277
|
-
return this.httpClient.put(`/api/v1/projects/${projectId}`, data);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Удаляет проект
|
|
281
|
-
* @param {string} projectId ID проекта
|
|
282
|
-
* @returns {Promise<void>}
|
|
283
|
-
*/
|
|
284
|
-
async deleteProject(projectId) {
|
|
285
|
-
return this.httpClient.delete(`/api/v1/projects/${projectId}`);
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Запускает индексацию проекта
|
|
289
|
-
* @param {string} projectId ID проекта
|
|
290
|
-
* @returns {Promise<IndexingResponse>} Информация о начатой индексации
|
|
291
|
-
*/
|
|
292
|
-
async indexProject(projectId) {
|
|
293
|
-
return this.httpClient.post(`/api/v1/projects/${projectId}/index`);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Останавливает индексацию проекта
|
|
297
|
-
* @param {string} projectId ID проекта
|
|
298
|
-
* @returns {Promise<void>}
|
|
299
|
-
*/
|
|
300
|
-
async stopIndexing(projectId) {
|
|
301
|
-
return this.httpClient.post(`/api/v1/projects/${projectId}/cancel-indexing`);
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Получает статус индексации проекта
|
|
305
|
-
* @param {string} projectId ID проекта
|
|
306
|
-
* @returns {Promise<IndexingStatus>} Статус индексации
|
|
307
|
-
*/
|
|
308
|
-
async getIndexingStatus(projectId) {
|
|
309
|
-
return this.httpClient.get(`/api/v1/projects/${projectId}/indexing-status`);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* API для поиска кода
|
|
315
|
-
*/
|
|
316
|
-
class SearchApi {
|
|
317
|
-
/**
|
|
318
|
-
* Создает новый экземпляр API для поиска кода
|
|
319
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
320
|
-
*/
|
|
321
|
-
constructor(httpClient) {
|
|
322
|
-
this.httpClient = httpClient;
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Выполняет поиск кода в проекте
|
|
326
|
-
* @param {string} projectId Идентификатор проекта
|
|
327
|
-
* @param {SearchCodeParams} params Параметры поиска
|
|
328
|
-
* @returns {Promise<SearchResults>} Результаты поиска
|
|
329
|
-
*/
|
|
330
|
-
async searchCode(projectId, params) {
|
|
331
|
-
return this.httpClient.post(`/api/v1/search/project/${projectId}`, params);
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Выполняет семантический поиск кода в проекте
|
|
335
|
-
* @param {string} projectId Идентификатор проекта
|
|
336
|
-
* @param {SearchCodeParams} params Параметры поиска
|
|
337
|
-
* @returns {Promise<SearchResults>} Результаты поиска
|
|
338
|
-
*/
|
|
339
|
-
async semanticSearch(projectId, params) {
|
|
340
|
-
return this.httpClient.post(`/api/v1/search/project/${projectId}`, { ...params, semantic: true });
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Получает популярные поисковые запросы
|
|
344
|
-
* @param {string} projectId Идентификатор проекта
|
|
345
|
-
* @param {number} [limit=10] Лимит результатов
|
|
346
|
-
* @returns {Promise<string[]>} Популярные поисковые запросы
|
|
347
|
-
*/
|
|
348
|
-
async getPopularQueries(projectId, limit = 10) {
|
|
349
|
-
return this.httpClient.get(`/api/projects/${projectId}/popular-queries`, { limit });
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Получает подсказки для автозаполнения поискового запроса
|
|
353
|
-
* @param {string} projectId Идентификатор проекта
|
|
354
|
-
* @param {string} query Начало поискового запроса
|
|
355
|
-
* @param {number} [limit=5] Лимит результатов
|
|
356
|
-
* @returns {Promise<string[]>} Подсказки для автозаполнения
|
|
357
|
-
*/
|
|
358
|
-
async getQuerySuggestions(projectId, query, limit = 5) {
|
|
359
|
-
return this.httpClient.get(`/api/projects/${projectId}/query-suggestions`, { query, limit });
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* API для работы с контекстом
|
|
365
|
-
*/
|
|
366
|
-
class ContextApi {
|
|
367
|
-
/**
|
|
368
|
-
* Создает новый экземпляр API для работы с контекстом
|
|
369
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
370
|
-
*/
|
|
371
|
-
constructor(httpClient) {
|
|
372
|
-
this.httpClient = httpClient;
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Определяет контекст для запроса
|
|
376
|
-
* @param {DetectContextParams} params Параметры определения контекста
|
|
377
|
-
* @returns {Promise<AutoContext>} Определенный контекст
|
|
378
|
-
*/
|
|
379
|
-
async detectContext(params) {
|
|
380
|
-
return this.httpClient.post('/api/context/detect', params);
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Получает содержимое файла
|
|
384
|
-
* @param {string} projectId Идентификатор проекта
|
|
385
|
-
* @param {string} filePath Путь к файлу
|
|
386
|
-
* @returns {Promise<string>} Содержимое файла
|
|
387
|
-
*/
|
|
388
|
-
async getFileContent(projectId, filePath) {
|
|
389
|
-
return this.httpClient.get(`/api/projects/${projectId}/files`, { path: filePath });
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Получает содержимое фрагмента файла
|
|
393
|
-
* @param {string} projectId Идентификатор проекта
|
|
394
|
-
* @param {string} filePath Путь к файлу
|
|
395
|
-
* @param {number} startLine Начальная строка
|
|
396
|
-
* @param {number} endLine Конечная строка
|
|
397
|
-
* @returns {Promise<CodeSnippet>} Фрагмент кода
|
|
398
|
-
*/
|
|
399
|
-
async getFileSnippet(projectId, filePath, startLine, endLine) {
|
|
400
|
-
return this.httpClient.get(`/api/projects/${projectId}/snippets`, {
|
|
401
|
-
path: filePath,
|
|
402
|
-
startLine,
|
|
403
|
-
endLine
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Получает структуру директории
|
|
408
|
-
* @param {string} projectId Идентификатор проекта
|
|
409
|
-
* @param {string} [dirPath='/'] Путь к директории
|
|
410
|
-
* @returns {Promise<Array<{name: string, type: 'file' | 'directory', path: string}>>} Структура директории
|
|
411
|
-
*/
|
|
412
|
-
async getDirectoryStructure(projectId, dirPath = '/') {
|
|
413
|
-
return this.httpClient.get(`/api/projects/${projectId}/directory`, { path: dirPath });
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* API для работы с рассуждениями
|
|
419
|
-
*/
|
|
420
|
-
class ReasoningApi {
|
|
421
|
-
/**
|
|
422
|
-
* Создает новый экземпляр API для работы с рассуждениями
|
|
423
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
424
|
-
*/
|
|
425
|
-
constructor(httpClient) {
|
|
426
|
-
this.httpClient = httpClient;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Получает список рассуждений
|
|
430
|
-
* @param {GetReasoningsParams} [params] Параметры для получения списка
|
|
431
|
-
* @returns {Promise<Reasoning[]>} Список рассуждений
|
|
432
|
-
*/
|
|
433
|
-
async getReasonings(params) {
|
|
434
|
-
return this.httpClient.get('/api/reasonings', params);
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Получает рассуждение по ID
|
|
438
|
-
* @param {string} reasoningId ID рассуждения
|
|
439
|
-
* @returns {Promise<Reasoning>} Рассуждение
|
|
440
|
-
*/
|
|
441
|
-
async getReasoning(reasoningId) {
|
|
442
|
-
return this.httpClient.get(`/api/v1/reasoning/${reasoningId}`);
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Создает новое рассуждение
|
|
446
|
-
* @param {ReasoningOptions} options Опции для рассуждения
|
|
447
|
-
* @returns {Promise<Reasoning>} Созданное рассуждение
|
|
448
|
-
*/
|
|
449
|
-
async createReasoning(options) {
|
|
450
|
-
return this.httpClient.post('/api/v1/reasoning/create', options);
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Запускает рассуждение
|
|
454
|
-
* @param {string} reasoningId ID рассуждения
|
|
455
|
-
* @returns {Promise<Reasoning>} Обновленное рассуждение
|
|
456
|
-
*/
|
|
457
|
-
async startReasoning(reasoningId) {
|
|
458
|
-
return this.httpClient.post(`/api/v1/reasoning/start/${reasoningId}`);
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Останавливает рассуждение
|
|
462
|
-
* @param {string} reasoningId ID рассуждения
|
|
463
|
-
* @returns {Promise<Reasoning>} Обновленное рассуждение
|
|
464
|
-
*/
|
|
465
|
-
async stopReasoning(reasoningId) {
|
|
466
|
-
return this.httpClient.post(`/api/v1/reasoning/cancel/${reasoningId}`);
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Удаляет рассуждение
|
|
470
|
-
* @param {string} reasoningId ID рассуждения
|
|
471
|
-
* @returns {Promise<void>}
|
|
472
|
-
*/
|
|
473
|
-
async deleteReasoning(reasoningId) {
|
|
474
|
-
return this.httpClient.delete(`/api/v1/reasoning/${reasoningId}`);
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* Получает ход мыслей рассуждения
|
|
478
|
-
* @param {string} reasoningId ID рассуждения
|
|
479
|
-
* @returns {Promise<ThinkingStep[]>} Ход мыслей
|
|
480
|
-
*/
|
|
481
|
-
async getThinking(reasoningId) {
|
|
482
|
-
return this.httpClient.get(`/api/v1/reasoning/${reasoningId}/thinking`);
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Получает все рассуждения проекта
|
|
486
|
-
* @param {string} projectId ID проекта
|
|
487
|
-
* @returns {Promise<Reasoning[]>} Список рассуждений
|
|
488
|
-
*/
|
|
489
|
-
async getAllReasonings(projectId) {
|
|
490
|
-
return this.httpClient.get(`/api/v1/reasoning/project/${projectId}`);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* API для модификации кода
|
|
496
|
-
*/
|
|
497
|
-
class CodeModificationApi {
|
|
498
|
-
/**
|
|
499
|
-
* Создает новый экземпляр API для модификации кода
|
|
500
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
501
|
-
*/
|
|
502
|
-
constructor(httpClient) {
|
|
503
|
-
this.httpClient = httpClient;
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Выполняет модификацию кода
|
|
507
|
-
* @param {CodeModificationParams} params Параметры модификации
|
|
508
|
-
* @returns {Promise<CodeModificationResult>} Результат модификации
|
|
509
|
-
*/
|
|
510
|
-
async modifyCode(params) {
|
|
511
|
-
return this.httpClient.post('/api/code-modifications', params);
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Применяет результат модификации к файлу
|
|
515
|
-
* @param {string} modificationId Идентификатор модификации
|
|
516
|
-
* @returns {Promise<CodeModificationResult>} Обновленный результат модификации
|
|
517
|
-
*/
|
|
518
|
-
async applyModification(modificationId) {
|
|
519
|
-
return this.httpClient.post(`/api/code-modifications/${modificationId}/apply`);
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Отменяет применение модификации
|
|
523
|
-
* @param {string} modificationId Идентификатор модификации
|
|
524
|
-
* @returns {Promise<CodeModificationResult>} Обновленный результат модификации
|
|
525
|
-
*/
|
|
526
|
-
async revertModification(modificationId) {
|
|
527
|
-
return this.httpClient.post(`/api/code-modifications/${modificationId}/revert`);
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Получает модификацию по идентификатору
|
|
531
|
-
* @param {string} modificationId Идентификатор модификации
|
|
532
|
-
* @returns {Promise<CodeModificationResult>} Результат модификации
|
|
533
|
-
*/
|
|
534
|
-
async getModification(modificationId) {
|
|
535
|
-
return this.httpClient.get(`/api/code-modifications/${modificationId}`);
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Получает список модификаций для проекта
|
|
539
|
-
* @param {string} projectId Идентификатор проекта
|
|
540
|
-
* @param {object} [params] Параметры запроса
|
|
541
|
-
* @param {number} [params.limit] Лимит результатов
|
|
542
|
-
* @param {number} [params.offset] Смещение для пагинации
|
|
543
|
-
* @returns {Promise<CodeModificationResult[]>} Список результатов модификации
|
|
544
|
-
*/
|
|
545
|
-
async getModifications(projectId, params) {
|
|
546
|
-
return this.httpClient.get(`/api/projects/${projectId}/code-modifications`, params);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* Базовый класс для WebSocket клиентов
|
|
552
|
-
*/
|
|
553
|
-
class WebSocketClient {
|
|
554
|
-
/**
|
|
555
|
-
* Создает новый WebSocket клиент
|
|
556
|
-
* @param {string} url URL для подключения
|
|
557
|
-
* @param {WebSocketClientOptions} [options] Опции клиента
|
|
558
|
-
*/
|
|
559
|
-
constructor(url, options = {}) {
|
|
560
|
-
/** Экземпляр WebSocket */
|
|
561
|
-
this.webSocket = null;
|
|
562
|
-
/** Счетчик попыток переподключения */
|
|
563
|
-
this.retryCount = 0;
|
|
564
|
-
/** Флаг, указывающий, что соединение было закрыто намеренно */
|
|
565
|
-
this.intentionallyClosed = false;
|
|
566
|
-
/** Таймер переподключения */
|
|
567
|
-
this.reconnectTimer = null;
|
|
568
|
-
/** Таймер таймаута соединения */
|
|
569
|
-
this.connectionTimeoutTimer = null;
|
|
570
|
-
/** Обработчики событий */
|
|
571
|
-
this.eventHandlers = {};
|
|
572
|
-
/** Очередь сообщений для отправки после подключения */
|
|
573
|
-
this.messageQueue = [];
|
|
574
|
-
/** Состояние соединения */
|
|
575
|
-
this.connected = false;
|
|
576
|
-
this.url = url;
|
|
577
|
-
this.options = {
|
|
578
|
-
headers: options.headers || {},
|
|
579
|
-
connectionTimeout: options.connectionTimeout || 30000,
|
|
580
|
-
protocols: options.protocols || [],
|
|
581
|
-
maxRetries: options.maxRetries || 5,
|
|
582
|
-
retryDelay: options.retryDelay || 1000,
|
|
583
|
-
maxRetryDelay: options.maxRetryDelay || 30000,
|
|
584
|
-
autoReconnect: options.autoReconnect !== undefined ? options.autoReconnect : true
|
|
585
|
-
};
|
|
586
|
-
// Определяем среду выполнения
|
|
587
|
-
this.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
588
|
-
}
|
|
589
|
-
/**
|
|
590
|
-
* Подключается к WebSocket серверу
|
|
591
|
-
* @returns {Promise<void>}
|
|
592
|
-
*/
|
|
593
|
-
connect() {
|
|
594
|
-
// Если соединение уже установлено, возвращаем Promise.resolve
|
|
595
|
-
if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
|
|
596
|
-
return Promise.resolve();
|
|
597
|
-
}
|
|
598
|
-
// Сбрасываем флаг намеренного закрытия
|
|
599
|
-
this.intentionallyClosed = false;
|
|
600
|
-
return new Promise((resolve, reject) => {
|
|
601
|
-
try {
|
|
602
|
-
// Создаем новый экземпляр WebSocket
|
|
603
|
-
if (this.isBrowser) {
|
|
604
|
-
// Браузерное окружение
|
|
605
|
-
this.webSocket = new WebSocket(this.url, this.options.protocols);
|
|
606
|
-
}
|
|
607
|
-
else {
|
|
608
|
-
// Node.js окружение
|
|
609
|
-
try {
|
|
610
|
-
// Динамически импортируем ws модуль в Node.js
|
|
611
|
-
const WebSocketImpl = require('ws');
|
|
612
|
-
this.webSocket = new WebSocketImpl(this.url, {
|
|
613
|
-
headers: this.options.headers,
|
|
614
|
-
protocol: this.options.protocols
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
catch (error) {
|
|
618
|
-
reject(new Error('Не удалось загрузить модуль ws в Node.js: ' + error.message));
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
// Устанавливаем таймаут соединения
|
|
623
|
-
this.connectionTimeoutTimer = setTimeout(() => {
|
|
624
|
-
if (this.webSocket && this.webSocket.readyState !== WebSocket.OPEN) {
|
|
625
|
-
reject(new Error('Таймаут подключения WebSocket'));
|
|
626
|
-
this.close();
|
|
627
|
-
}
|
|
628
|
-
}, this.options.connectionTimeout);
|
|
629
|
-
// Обработчик открытия соединения
|
|
630
|
-
this.webSocket.onopen = () => {
|
|
631
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
632
|
-
this.retryCount = 0;
|
|
633
|
-
this.connected = true;
|
|
634
|
-
// Отправляем сообщения из очереди
|
|
635
|
-
while (this.messageQueue.length > 0) {
|
|
636
|
-
const message = this.messageQueue.shift();
|
|
637
|
-
if (message && this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
|
|
638
|
-
this.webSocket.send(message);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
resolve();
|
|
642
|
-
this.dispatchEvent('open', {});
|
|
643
|
-
};
|
|
644
|
-
// Обработчик сообщений
|
|
645
|
-
this.webSocket.onmessage = (event) => {
|
|
646
|
-
try {
|
|
647
|
-
// Пытаемся распарсить сообщение как JSON
|
|
648
|
-
let data = event.data;
|
|
649
|
-
if (typeof data === 'string') {
|
|
650
|
-
try {
|
|
651
|
-
data = JSON.parse(data);
|
|
652
|
-
}
|
|
653
|
-
catch (e) {
|
|
654
|
-
// Если не удалось распарсить, оставляем как есть
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
this.dispatchEvent('message', data);
|
|
658
|
-
}
|
|
659
|
-
catch (e) {
|
|
660
|
-
console.error('Ошибка при обработке сообщения WebSocket:', e);
|
|
661
|
-
}
|
|
662
|
-
};
|
|
663
|
-
// Обработчик закрытия соединения
|
|
664
|
-
this.webSocket.onclose = (event) => {
|
|
665
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
666
|
-
this.connected = false;
|
|
667
|
-
this.dispatchEvent('close', { code: event.code, reason: event.reason });
|
|
668
|
-
// Если соединение было закрыто намеренно, не пытаемся переподключиться
|
|
669
|
-
if (this.intentionallyClosed) {
|
|
670
|
-
return;
|
|
671
|
-
}
|
|
672
|
-
// Если включено автоматическое переподключение, пытаемся переподключиться
|
|
673
|
-
if (this.options.autoReconnect) {
|
|
674
|
-
this.reconnect();
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
// Обработчик ошибок
|
|
678
|
-
this.webSocket.onerror = (error) => {
|
|
679
|
-
this.dispatchEvent('error', error);
|
|
680
|
-
// Если соединение не установлено и это первая попытка, отклоняем Promise
|
|
681
|
-
if (!this.connected && this.retryCount === 0) {
|
|
682
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
683
|
-
reject(new Error('Ошибка подключения WebSocket'));
|
|
684
|
-
}
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
catch (error) {
|
|
688
|
-
reject(error);
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Переподключается к WebSocket серверу
|
|
694
|
-
* @private
|
|
695
|
-
*/
|
|
696
|
-
reconnect() {
|
|
697
|
-
// Увеличиваем счетчик попыток
|
|
698
|
-
this.retryCount++;
|
|
699
|
-
// Если превышено максимальное количество попыток, не пытаемся переподключиться
|
|
700
|
-
if (this.retryCount > (this.options.maxRetries || 5)) {
|
|
701
|
-
this.dispatchEvent('maxRetries', { retries: this.retryCount });
|
|
702
|
-
return;
|
|
703
|
-
}
|
|
704
|
-
// Вычисляем задержку перед переподключением с экспоненциальным ростом
|
|
705
|
-
const delay = Math.min((this.options.retryDelay || 1000) * Math.pow(2, this.retryCount - 1), this.options.maxRetryDelay || 30000);
|
|
706
|
-
// Пытаемся переподключиться после задержки
|
|
707
|
-
this.reconnectTimer = setTimeout(() => {
|
|
708
|
-
this.dispatchEvent('reconnect', { attempt: this.retryCount });
|
|
709
|
-
this.connect().catch(() => { });
|
|
710
|
-
}, delay);
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Закрывает WebSocket соединение
|
|
714
|
-
* @param {number} [code=1000] Код закрытия
|
|
715
|
-
* @param {string} [reason] Причина закрытия
|
|
716
|
-
*/
|
|
717
|
-
close(code = 1000, reason) {
|
|
718
|
-
this.intentionallyClosed = true;
|
|
719
|
-
// Очищаем таймеры
|
|
720
|
-
clearTimeout(this.reconnectTimer);
|
|
721
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
722
|
-
// Очищаем очередь сообщений
|
|
723
|
-
this.messageQueue = [];
|
|
724
|
-
// Закрываем соединение
|
|
725
|
-
if (this.webSocket) {
|
|
726
|
-
if (this.webSocket.readyState === WebSocket.OPEN) {
|
|
727
|
-
this.webSocket.close(code, reason);
|
|
728
|
-
}
|
|
729
|
-
this.webSocket = null;
|
|
730
|
-
}
|
|
731
|
-
this.connected = false;
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* Отправляет сообщение через WebSocket
|
|
735
|
-
* @param {string | object} message Сообщение для отправки
|
|
736
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
737
|
-
*/
|
|
738
|
-
send(message) {
|
|
739
|
-
const data = typeof message === 'string' ? message : JSON.stringify(message);
|
|
740
|
-
if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
|
|
741
|
-
this.webSocket.send(data);
|
|
742
|
-
return true;
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
// Если соединение не установлено, добавляем сообщение в очередь
|
|
746
|
-
this.messageQueue.push(data);
|
|
747
|
-
// Если соединение не установлено и не закрыто намеренно, пытаемся подключиться
|
|
748
|
-
if ((!this.webSocket || this.webSocket.readyState === WebSocket.CLOSED) && !this.intentionallyClosed) {
|
|
749
|
-
this.connect().catch(() => { });
|
|
750
|
-
}
|
|
751
|
-
return false;
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
* Проверяет, установлено ли соединение
|
|
756
|
-
* @returns {boolean} Установлено ли соединение
|
|
757
|
-
*/
|
|
758
|
-
isConnected() {
|
|
759
|
-
return this.webSocket !== null && this.webSocket.readyState === WebSocket.OPEN;
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* Добавляет обработчик события
|
|
763
|
-
* @param {string} eventType Тип события
|
|
764
|
-
* @param {WebSocketEventHandler} handler Обработчик события
|
|
765
|
-
*/
|
|
766
|
-
on(eventType, handler) {
|
|
767
|
-
if (!this.eventHandlers[eventType]) {
|
|
768
|
-
this.eventHandlers[eventType] = [];
|
|
769
|
-
}
|
|
770
|
-
this.eventHandlers[eventType].push(handler);
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Удаляет обработчик события
|
|
774
|
-
* @param {string} eventType Тип события
|
|
775
|
-
* @param {WebSocketEventHandler} [handler] Обработчик события (если не указан, удаляются все обработчики)
|
|
776
|
-
*/
|
|
777
|
-
off(eventType, handler) {
|
|
778
|
-
if (!this.eventHandlers[eventType]) {
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
if (!handler) {
|
|
782
|
-
// Если обработчик не указан, удаляем все обработчики для данного события
|
|
783
|
-
delete this.eventHandlers[eventType];
|
|
784
|
-
}
|
|
785
|
-
else {
|
|
786
|
-
// Если обработчик указан, удаляем только его
|
|
787
|
-
this.eventHandlers[eventType] = this.eventHandlers[eventType].filter(h => h !== handler);
|
|
788
|
-
// Если обработчиков больше нет, удаляем массив
|
|
789
|
-
if (this.eventHandlers[eventType].length === 0) {
|
|
790
|
-
delete this.eventHandlers[eventType];
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Вызывает обработчики для указанного события
|
|
796
|
-
* @param {string} eventType Тип события
|
|
797
|
-
* @param {any} data Данные события
|
|
798
|
-
*/
|
|
799
|
-
dispatchEvent(eventType, data) {
|
|
800
|
-
if (!this.eventHandlers[eventType]) {
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
for (const handler of this.eventHandlers[eventType]) {
|
|
804
|
-
try {
|
|
805
|
-
handler(data);
|
|
806
|
-
}
|
|
807
|
-
catch (e) {
|
|
808
|
-
console.error(`Ошибка в обработчике события ${eventType}:`, e);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* Пространства имен для WebSocket
|
|
816
|
-
*/
|
|
817
|
-
var WebSocketNamespace;
|
|
818
|
-
(function (WebSocketNamespace) {
|
|
819
|
-
/** Пространство имен для рассуждений */
|
|
820
|
-
WebSocketNamespace["REASONING"] = "reasoning";
|
|
821
|
-
/** Пространство имен для индексации */
|
|
822
|
-
WebSocketNamespace["INDEXING"] = "indexing";
|
|
823
|
-
/** Пространство имен для уведомлений */
|
|
824
|
-
WebSocketNamespace["NOTIFICATIONS"] = "notifications";
|
|
825
|
-
})(WebSocketNamespace || (WebSocketNamespace = {}));
|
|
826
|
-
/**
|
|
827
|
-
* WebSocket клиент для работы с Code Solver API
|
|
828
|
-
*/
|
|
829
|
-
class CodeSolverWebSocketClient {
|
|
830
|
-
/**
|
|
831
|
-
* Создает новый WebSocket клиент для Code Solver API
|
|
832
|
-
* @param {string} baseURL Базовый URL API
|
|
833
|
-
* @param {CodeSolverWebSocketOptions} [options] Опции клиента
|
|
834
|
-
*/
|
|
835
|
-
constructor(baseURL, options = {}) {
|
|
836
|
-
/** WebSocket клиенты для разных пространств имен */
|
|
837
|
-
this.clients = new Map();
|
|
838
|
-
/** Активная сессия рассуждения */
|
|
839
|
-
this.activeReasoningId = null;
|
|
840
|
-
/** Активная сессия индексации */
|
|
841
|
-
this.activeProjectId = null;
|
|
842
|
-
this.baseURL = baseURL.replace(/^http/, 'ws');
|
|
843
|
-
this.options = {
|
|
844
|
-
...options,
|
|
845
|
-
headers: {
|
|
846
|
-
...(options.headers || {}),
|
|
847
|
-
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {})
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
/**
|
|
852
|
-
* Подключается к пространству имен WebSocket
|
|
853
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
854
|
-
* @param {Record<string, any>} [params] Параметры подключения
|
|
855
|
-
* @returns {Promise<WebSocketClient>} WebSocket клиент
|
|
856
|
-
*/
|
|
857
|
-
async connect(namespace, params = {}) {
|
|
858
|
-
// Если клиент уже существует, возвращаем его
|
|
859
|
-
if (this.clients.has(namespace)) {
|
|
860
|
-
const client = this.clients.get(namespace);
|
|
861
|
-
// Если клиент уже подключен, возвращаем его
|
|
862
|
-
if (client.isConnected()) {
|
|
863
|
-
return client;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
// Формируем URL для подключения
|
|
867
|
-
const url = new URL(`${this.baseURL}/${namespace}`);
|
|
868
|
-
// Добавляем параметры к URL
|
|
869
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
870
|
-
url.searchParams.append(key, String(value));
|
|
871
|
-
});
|
|
872
|
-
// Создаем новый WebSocket клиент
|
|
873
|
-
const client = new WebSocketClient(url.toString(), this.options);
|
|
874
|
-
// Подключаемся к серверу
|
|
875
|
-
await client.connect();
|
|
876
|
-
// Сохраняем клиент
|
|
877
|
-
this.clients.set(namespace, client);
|
|
878
|
-
return client;
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Подключается к сессии рассуждения
|
|
882
|
-
* @param {string} [reasoningId] Идентификатор рассуждения
|
|
883
|
-
* @returns {Promise<void>}
|
|
884
|
-
*/
|
|
885
|
-
async connectToReasoning(reasoningId) {
|
|
886
|
-
// Если reasoningId не указан, используем активный
|
|
887
|
-
const id = reasoningId || this.activeReasoningId;
|
|
888
|
-
if (!id) {
|
|
889
|
-
throw new Error('Необходимо указать идентификатор рассуждения');
|
|
890
|
-
}
|
|
891
|
-
// Сохраняем активный идентификатор рассуждения
|
|
892
|
-
this.activeReasoningId = id;
|
|
893
|
-
// Подключаемся к пространству имен
|
|
894
|
-
await this.connect(WebSocketNamespace.REASONING, { reasoningId: id });
|
|
895
|
-
}
|
|
896
|
-
/**
|
|
897
|
-
* Подключается к сессии индексации проекта
|
|
898
|
-
* @param {string} [projectId] Идентификатор проекта
|
|
899
|
-
* @returns {Promise<void>}
|
|
900
|
-
*/
|
|
901
|
-
async connectToIndexing(projectId) {
|
|
902
|
-
// Если projectId не указан, используем активный
|
|
903
|
-
const id = projectId || this.activeProjectId;
|
|
904
|
-
if (!id) {
|
|
905
|
-
throw new Error('Необходимо указать идентификатор проекта');
|
|
906
|
-
}
|
|
907
|
-
// Сохраняем активный идентификатор проекта
|
|
908
|
-
this.activeProjectId = id;
|
|
909
|
-
// Подключаемся к пространству имен
|
|
910
|
-
await this.connect(WebSocketNamespace.INDEXING, { projectId: id });
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Подключается к уведомлениям
|
|
914
|
-
* @returns {Promise<void>}
|
|
915
|
-
*/
|
|
916
|
-
async connectToNotifications() {
|
|
917
|
-
// Подключаемся к пространству имен
|
|
918
|
-
await this.connect(WebSocketNamespace.NOTIFICATIONS);
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Отключается от пространства имен
|
|
922
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
923
|
-
*/
|
|
924
|
-
disconnect(namespace) {
|
|
925
|
-
const client = this.clients.get(namespace);
|
|
926
|
-
if (client) {
|
|
927
|
-
client.close();
|
|
928
|
-
this.clients.delete(namespace);
|
|
929
|
-
}
|
|
930
|
-
// Сбрасываем активные сессии
|
|
931
|
-
if (namespace === WebSocketNamespace.REASONING) {
|
|
932
|
-
this.activeReasoningId = null;
|
|
933
|
-
}
|
|
934
|
-
else if (namespace === WebSocketNamespace.INDEXING) {
|
|
935
|
-
this.activeProjectId = null;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
/**
|
|
939
|
-
* Отключается от всех пространств имен
|
|
940
|
-
*/
|
|
941
|
-
disconnectAll() {
|
|
942
|
-
for (const [namespace, client] of this.clients.entries()) {
|
|
943
|
-
client.close();
|
|
944
|
-
this.clients.delete(namespace);
|
|
945
|
-
}
|
|
946
|
-
// Сбрасываем активные сессии
|
|
947
|
-
this.activeReasoningId = null;
|
|
948
|
-
this.activeProjectId = null;
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* Добавляет обработчик события для пространства имен
|
|
952
|
-
* @param {string} eventType Тип события
|
|
953
|
-
* @param {Function} handler Обработчик события
|
|
954
|
-
* @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, добавляется ко всем активным)
|
|
955
|
-
*/
|
|
956
|
-
on(eventType, handler, namespace) {
|
|
957
|
-
if (namespace) {
|
|
958
|
-
// Если указано пространство имен, добавляем обработчик только к нему
|
|
959
|
-
const client = this.clients.get(namespace);
|
|
960
|
-
if (!client) {
|
|
961
|
-
throw new Error(`Не подключен к пространству имен ${namespace}`);
|
|
962
|
-
}
|
|
963
|
-
client.on(eventType, handler);
|
|
964
|
-
}
|
|
965
|
-
else {
|
|
966
|
-
// Если пространство имен не указано, добавляем обработчик ко всем активным пространствам
|
|
967
|
-
for (const client of this.clients.values()) {
|
|
968
|
-
client.on(eventType, handler);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
/**
|
|
973
|
-
* Удаляет обработчик события для пространства имен
|
|
974
|
-
* @param {string} eventType Тип события
|
|
975
|
-
* @param {Function} [handler] Обработчик события (если не указан, удаляются все обработчики)
|
|
976
|
-
* @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, удаляется из всех активных)
|
|
977
|
-
*/
|
|
978
|
-
off(eventType, handler, namespace) {
|
|
979
|
-
if (namespace) {
|
|
980
|
-
// Если указано пространство имен, удаляем обработчик только из него
|
|
981
|
-
const client = this.clients.get(namespace);
|
|
982
|
-
if (!client) {
|
|
983
|
-
return;
|
|
984
|
-
}
|
|
985
|
-
client.off(eventType, handler);
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
// Если пространство имен не указано, удаляем обработчик из всех активных пространств
|
|
989
|
-
for (const client of this.clients.values()) {
|
|
990
|
-
client.off(eventType, handler);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
/**
|
|
995
|
-
* Отправляет сообщение в пространство имен
|
|
996
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
997
|
-
* @param {string} eventType Тип события
|
|
998
|
-
* @param {any} [data] Данные сообщения
|
|
999
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1000
|
-
*/
|
|
1001
|
-
send(namespace, eventType, data) {
|
|
1002
|
-
const client = this.clients.get(namespace);
|
|
1003
|
-
if (!client) {
|
|
1004
|
-
throw new Error(`Не подключен к пространству имен ${namespace}`);
|
|
1005
|
-
}
|
|
1006
|
-
return client.send({
|
|
1007
|
-
event: eventType,
|
|
1008
|
-
data
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Отправляет сообщение в активную сессию рассуждения
|
|
1013
|
-
* @param {string} eventType Тип события
|
|
1014
|
-
* @param {any} [data] Данные сообщения
|
|
1015
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1016
|
-
*/
|
|
1017
|
-
sendToReasoning(eventType, data) {
|
|
1018
|
-
if (!this.activeReasoningId) {
|
|
1019
|
-
throw new Error('Не подключен к сессии рассуждения');
|
|
1020
|
-
}
|
|
1021
|
-
return this.send(WebSocketNamespace.REASONING, eventType, data);
|
|
1022
|
-
}
|
|
1023
|
-
/**
|
|
1024
|
-
* Отправляет сообщение в активную сессию индексации
|
|
1025
|
-
* @param {string} eventType Тип события
|
|
1026
|
-
* @param {any} [data] Данные сообщения
|
|
1027
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1028
|
-
*/
|
|
1029
|
-
sendToIndexing(eventType, data) {
|
|
1030
|
-
if (!this.activeProjectId) {
|
|
1031
|
-
throw new Error('Не подключен к сессии индексации');
|
|
1032
|
-
}
|
|
1033
|
-
return this.send(WebSocketNamespace.INDEXING, eventType, data);
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Отправляет сообщение в уведомления
|
|
1037
|
-
* @param {string} eventType Тип события
|
|
1038
|
-
* @param {any} [data] Данные сообщения
|
|
1039
|
-
* @returns {boolean} Успешно ли отправлено сообщение
|
|
1040
|
-
*/
|
|
1041
|
-
sendToNotifications(eventType, data) {
|
|
1042
|
-
return this.send(WebSocketNamespace.NOTIFICATIONS, eventType, data);
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Проверяет, подключен ли клиент к указанному пространству имен
|
|
1046
|
-
* @param {WebSocketNamespace} namespace Пространство имен
|
|
1047
|
-
* @returns {boolean} Статус подключения
|
|
1048
|
-
*/
|
|
1049
|
-
isConnected(namespace) {
|
|
1050
|
-
const client = this.clients.get(namespace);
|
|
1051
|
-
return client ? client.isConnected() : false;
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
* Проверяет, подключен ли клиент к пространству имен рассуждений
|
|
1055
|
-
* @returns {boolean} Статус подключения
|
|
1056
|
-
*/
|
|
1057
|
-
isConnectedToReasoning() {
|
|
1058
|
-
return this.isConnected(WebSocketNamespace.REASONING);
|
|
1059
|
-
}
|
|
1060
|
-
/**
|
|
1061
|
-
* Проверяет, подключен ли клиент к пространству имен индексации
|
|
1062
|
-
* @returns {boolean} Статус подключения
|
|
1063
|
-
*/
|
|
1064
|
-
isConnectedToIndexing() {
|
|
1065
|
-
return this.isConnected(WebSocketNamespace.INDEXING);
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* Проверяет, подключен ли клиент к пространству имен уведомлений
|
|
1069
|
-
* @returns {boolean} Статус подключения
|
|
1070
|
-
*/
|
|
1071
|
-
isConnectedToNotifications() {
|
|
1072
|
-
return this.isConnected(WebSocketNamespace.NOTIFICATIONS);
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
/**
|
|
1077
|
-
* API для работы с агентами
|
|
1078
|
-
*/
|
|
1079
|
-
class AgentsApi {
|
|
1080
|
-
/**
|
|
1081
|
-
* Создает новый экземпляр API для работы с агентами
|
|
1082
|
-
* @param {HttpClient} httpClient HTTP клиент
|
|
1083
|
-
*/
|
|
1084
|
-
constructor(httpClient) {
|
|
1085
|
-
this.httpClient = httpClient;
|
|
1086
|
-
}
|
|
1087
|
-
/**
|
|
1088
|
-
* Получает список всех агентов проекта
|
|
1089
|
-
* @param {string} projectId Идентификатор проекта
|
|
1090
|
-
* @returns {Promise<Agent[]>} Список агентов
|
|
1091
|
-
*/
|
|
1092
|
-
async getAgents(projectId) {
|
|
1093
|
-
return this.httpClient.get(`/api/projects/${projectId}/agents`);
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Получает агента по идентификатору
|
|
1097
|
-
* @param {string} agentId Идентификатор агента
|
|
1098
|
-
* @returns {Promise<Agent>} Агент
|
|
1099
|
-
*/
|
|
1100
|
-
async getAgent(agentId) {
|
|
1101
|
-
return this.httpClient.get(`/api/agents/${agentId}`);
|
|
1102
|
-
}
|
|
1103
|
-
/**
|
|
1104
|
-
* Создает нового агента
|
|
1105
|
-
* @param {CreateAgentParams} params Параметры создания агента
|
|
1106
|
-
* @returns {Promise<Agent>} Созданный агент
|
|
1107
|
-
*/
|
|
1108
|
-
async createAgent(params) {
|
|
1109
|
-
return this.httpClient.post('/api/agents', params);
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
* Обновляет агента
|
|
1113
|
-
* @param {string} agentId Идентификатор агента
|
|
1114
|
-
* @param {Partial<Pick<Agent, 'name' | 'description' | 'settings'>>} data Данные для обновления
|
|
1115
|
-
* @returns {Promise<Agent>} Обновленный агент
|
|
1116
|
-
*/
|
|
1117
|
-
async updateAgent(agentId, data) {
|
|
1118
|
-
return this.httpClient.put(`/api/agents/${agentId}`, data);
|
|
1119
|
-
}
|
|
1120
|
-
/**
|
|
1121
|
-
* Удаляет агента
|
|
1122
|
-
* @param {string} agentId Идентификатор агента
|
|
1123
|
-
* @returns {Promise<void>}
|
|
1124
|
-
*/
|
|
1125
|
-
async deleteAgent(agentId) {
|
|
1126
|
-
return this.httpClient.delete(`/api/agents/${agentId}`);
|
|
1127
|
-
}
|
|
1128
|
-
/**
|
|
1129
|
-
* Запускает агента
|
|
1130
|
-
* @param {string} agentId Идентификатор агента
|
|
1131
|
-
* @param {object} [params] Параметры запуска
|
|
1132
|
-
* @returns {Promise<Agent>} Обновленный агент
|
|
1133
|
-
*/
|
|
1134
|
-
async startAgent(agentId, params) {
|
|
1135
|
-
return this.httpClient.post(`/api/agents/${agentId}/start`, params);
|
|
1136
|
-
}
|
|
1137
|
-
/**
|
|
1138
|
-
* Останавливает агента
|
|
1139
|
-
* @param {string} agentId Идентификатор агента
|
|
1140
|
-
* @returns {Promise<Agent>} Обновленный агент
|
|
1141
|
-
*/
|
|
1142
|
-
async stopAgent(agentId) {
|
|
1143
|
-
return this.httpClient.post(`/api/agents/${agentId}/stop`);
|
|
1144
|
-
}
|
|
1145
|
-
/**
|
|
1146
|
-
* Получает задачи агента
|
|
1147
|
-
* @param {string} agentId Идентификатор агента
|
|
1148
|
-
* @returns {Promise<AgentTask[]>} Список задач
|
|
1149
|
-
*/
|
|
1150
|
-
async getAgentTasks(agentId) {
|
|
1151
|
-
return this.httpClient.get(`/api/agents/${agentId}/tasks`);
|
|
1152
|
-
}
|
|
1153
|
-
/**
|
|
1154
|
-
* Создает новую задачу для агента
|
|
1155
|
-
* @param {string} agentId Идентификатор агента
|
|
1156
|
-
* @param {object} params Параметры задачи
|
|
1157
|
-
* @param {string} params.description Описание задачи
|
|
1158
|
-
* @param {object} [params.context] Контекст задачи
|
|
1159
|
-
* @returns {Promise<AgentTask>} Созданная задача
|
|
1160
|
-
*/
|
|
1161
|
-
async createAgentTask(agentId, params) {
|
|
1162
|
-
return this.httpClient.post(`/api/agents/${agentId}/tasks`, params);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
// Версия SDK
|
|
1167
|
-
const SDK_VERSION = '1.0.0';
|
|
1168
|
-
/**
|
|
1169
|
-
* Определение типа среды выполнения
|
|
1170
|
-
* @returns 'browser' | 'node' | 'unknown'
|
|
1171
|
-
*/
|
|
1172
|
-
function getEnvironment() {
|
|
1173
|
-
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
|
|
1174
|
-
return 'browser';
|
|
1175
|
-
}
|
|
1176
|
-
else if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
|
1177
|
-
return 'node';
|
|
1178
|
-
}
|
|
1179
|
-
return 'unknown';
|
|
1180
|
-
}
|
|
1181
|
-
/**
|
|
1182
|
-
* Основной класс SDK для работы с Code Solver API
|
|
1183
|
-
* Поддерживает работу как в браузере, так и в Node.js
|
|
1184
|
-
*/
|
|
1185
|
-
class CodeSolverSDK {
|
|
1186
|
-
/**
|
|
1187
|
-
* Создает новый экземпляр SDK
|
|
1188
|
-
* @param {CodeSolverSDKOptions} options Опции SDK
|
|
1189
|
-
*/
|
|
1190
|
-
constructor(options) {
|
|
1191
|
-
/** WebSocket клиент для работы с реалтайм API */
|
|
1192
|
-
this.wsClient = null;
|
|
1193
|
-
this._options = {
|
|
1194
|
-
...options,
|
|
1195
|
-
mode: options.mode || 'auto'
|
|
1196
|
-
};
|
|
1197
|
-
// Определяем среду выполнения
|
|
1198
|
-
this.environment = this._options.mode === 'auto'
|
|
1199
|
-
? getEnvironment()
|
|
1200
|
-
: this._options.mode === 'browser' ? 'browser' : 'node';
|
|
1201
|
-
// Инициализируем HTTP клиент
|
|
1202
|
-
this.httpClient = new HttpClient(this._options.baseURL, {
|
|
1203
|
-
headers: {
|
|
1204
|
-
...(this._options.apiKey ? { 'Authorization': `Bearer ${this._options.apiKey}` } : {}),
|
|
1205
|
-
...(this._options.headers || {})
|
|
1206
|
-
},
|
|
1207
|
-
timeout: this._options.timeout,
|
|
1208
|
-
httpsAgent: this.environment === 'node' ? this._options.httpsAgent : undefined
|
|
1209
|
-
});
|
|
1210
|
-
// Инициализируем API клиенты
|
|
1211
|
-
this._agents = new AgentsApi(this.httpClient);
|
|
1212
|
-
this._context = new ContextApi(this.httpClient);
|
|
1213
|
-
this._projects = new ProjectsApi(this.httpClient);
|
|
1214
|
-
this._search = new SearchApi(this.httpClient);
|
|
1215
|
-
this._reasoning = new ReasoningApi(this.httpClient);
|
|
1216
|
-
this._codeModification = new CodeModificationApi(this.httpClient);
|
|
1217
|
-
}
|
|
1218
|
-
/**
|
|
1219
|
-
* Проверяет доступность API
|
|
1220
|
-
* @returns {Promise<boolean>} Доступен ли API
|
|
1221
|
-
*/
|
|
1222
|
-
async checkHealth() {
|
|
1223
|
-
try {
|
|
1224
|
-
await this.httpClient.get('/health');
|
|
1225
|
-
return true;
|
|
1226
|
-
}
|
|
1227
|
-
catch (error) {
|
|
1228
|
-
return false;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Получает WebSocket клиент
|
|
1233
|
-
* @returns {CodeSolverWebSocketClient} WebSocket клиент
|
|
1234
|
-
*/
|
|
1235
|
-
getWebSocketClient() {
|
|
1236
|
-
if (!this.wsClient) {
|
|
1237
|
-
this.wsClient = new CodeSolverWebSocketClient(this._options.baseURL, {
|
|
1238
|
-
apiKey: this._options.apiKey,
|
|
1239
|
-
headers: this._options.headers
|
|
1240
|
-
});
|
|
1241
|
-
}
|
|
1242
|
-
return this.wsClient;
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* API для работы с агентами
|
|
1246
|
-
*/
|
|
1247
|
-
get agents() {
|
|
1248
|
-
return this._agents;
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* API для работы с контекстом
|
|
1252
|
-
*/
|
|
1253
|
-
get context() {
|
|
1254
|
-
return this._context;
|
|
1255
|
-
}
|
|
1256
|
-
/**
|
|
1257
|
-
* API для работы с проектами
|
|
1258
|
-
*/
|
|
1259
|
-
get projects() {
|
|
1260
|
-
return this._projects;
|
|
1261
|
-
}
|
|
1262
|
-
/**
|
|
1263
|
-
* API для поиска кода
|
|
1264
|
-
*/
|
|
1265
|
-
get search() {
|
|
1266
|
-
return this._search;
|
|
1267
|
-
}
|
|
1268
|
-
/**
|
|
1269
|
-
* API для работы с рассуждениями
|
|
1270
|
-
*/
|
|
1271
|
-
get reasoning() {
|
|
1272
|
-
return this._reasoning;
|
|
1273
|
-
}
|
|
1274
|
-
/**
|
|
1275
|
-
* API для модификации кода
|
|
1276
|
-
*/
|
|
1277
|
-
get codeModification() {
|
|
1278
|
-
return this._codeModification;
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Опции SDK
|
|
1282
|
-
*/
|
|
1283
|
-
get options() {
|
|
1284
|
-
return this._options;
|
|
1285
|
-
}
|
|
1286
|
-
/**
|
|
1287
|
-
* Получает текущую среду выполнения
|
|
1288
|
-
* @returns {string} Среда выполнения ('browser', 'node', 'unknown')
|
|
1289
|
-
*/
|
|
1290
|
-
getEnvironment() {
|
|
1291
|
-
return this.environment;
|
|
1292
|
-
}
|
|
1293
|
-
/**
|
|
1294
|
-
* Закрывает все соединения и освобождает ресурсы
|
|
1295
|
-
*/
|
|
1296
|
-
dispose() {
|
|
1297
|
-
if (this.wsClient) {
|
|
1298
|
-
this.wsClient.disconnectAll();
|
|
1299
|
-
this.wsClient = null;
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
/**
|
|
1303
|
-
* Устанавливает глобальный обработчик ошибок SDK
|
|
1304
|
-
* @param {(error: Error) => void} handler Функция-обработчик ошибок
|
|
1305
|
-
*/
|
|
1306
|
-
static setErrorHandler(handler) {
|
|
1307
|
-
CodeSolverSDK.errorHandler = handler;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Обрабатывает ошибку через глобальный обработчик, если он установлен
|
|
1311
|
-
* @param {Error} error Ошибка для обработки
|
|
1312
|
-
*/
|
|
1313
|
-
static handleError(error) {
|
|
1314
|
-
if (CodeSolverSDK.errorHandler) {
|
|
1315
|
-
CodeSolverSDK.errorHandler(error);
|
|
1316
|
-
}
|
|
1317
|
-
else {
|
|
1318
|
-
console.error('[CodeSolverSDK]', error);
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
/**
|
|
1322
|
-
* Возвращает текущую версию SDK
|
|
1323
|
-
* @returns {string} Версия SDK
|
|
1324
|
-
*/
|
|
1325
|
-
static getVersion() {
|
|
1326
|
-
return SDK_VERSION;
|
|
1327
|
-
}
|
|
1328
|
-
/**
|
|
1329
|
-
* Возвращает текущую версию SDK
|
|
1330
|
-
* @returns {string} Версия SDK
|
|
1331
|
-
*/
|
|
1332
|
-
getVersion() {
|
|
1333
|
-
return SDK_VERSION;
|
|
1334
|
-
}
|
|
1335
|
-
/**
|
|
1336
|
-
* Устанавливает новый API ключ для SDK
|
|
1337
|
-
* @param {string} apiKey Новый API ключ
|
|
1338
|
-
*/
|
|
1339
|
-
setApiKey(apiKey) {
|
|
1340
|
-
if (!apiKey) {
|
|
1341
|
-
throw new Error('API ключ не может быть пустым');
|
|
1342
|
-
}
|
|
1343
|
-
// Обновляем опции
|
|
1344
|
-
this._options.apiKey = apiKey;
|
|
1345
|
-
// Пересоздаем HTTP клиент с новым API ключом
|
|
1346
|
-
const newHttpClient = new HttpClient(this._options.baseURL, {
|
|
1347
|
-
headers: {
|
|
1348
|
-
...this._options.headers,
|
|
1349
|
-
'Authorization': `Bearer ${apiKey}`
|
|
1350
|
-
},
|
|
1351
|
-
timeout: this._options.timeout,
|
|
1352
|
-
httpsAgent: this.environment === 'node' ? this._options.httpsAgent : undefined
|
|
1353
|
-
});
|
|
1354
|
-
// Обновляем ссылки на клиент и API
|
|
1355
|
-
this.httpClient = newHttpClient;
|
|
1356
|
-
this._agents = new AgentsApi(newHttpClient);
|
|
1357
|
-
this._context = new ContextApi(newHttpClient);
|
|
1358
|
-
this._projects = new ProjectsApi(newHttpClient);
|
|
1359
|
-
this._search = new SearchApi(newHttpClient);
|
|
1360
|
-
this._reasoning = new ReasoningApi(newHttpClient);
|
|
1361
|
-
this._codeModification = new CodeModificationApi(newHttpClient);
|
|
1362
|
-
// Если есть WebSocket клиент, пересоздаем его
|
|
1363
|
-
if (this.wsClient) {
|
|
1364
|
-
const isConnected = this.wsClient.isConnectedToReasoning() || this.wsClient.isConnectedToIndexing();
|
|
1365
|
-
this.wsClient.disconnectAll();
|
|
1366
|
-
this.wsClient = new CodeSolverWebSocketClient(this._options.baseURL, {
|
|
1367
|
-
apiKey,
|
|
1368
|
-
headers: this._options.headers
|
|
1369
|
-
});
|
|
1370
|
-
// Если был подключен, восстанавливаем соединение
|
|
1371
|
-
if (isConnected) {
|
|
1372
|
-
this.connect().catch(() => { });
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
/**
|
|
1377
|
-
* Подключается к WebSocket серверу
|
|
1378
|
-
* @returns {Promise<boolean>} Promise с результатом подключения
|
|
1379
|
-
*/
|
|
1380
|
-
async connect() {
|
|
1381
|
-
try {
|
|
1382
|
-
const wsClient = this.getWebSocketClient();
|
|
1383
|
-
// Подключаемся к обоим пространствам имен
|
|
1384
|
-
await wsClient.connectToReasoning();
|
|
1385
|
-
await wsClient.connectToIndexing();
|
|
1386
|
-
return true;
|
|
1387
|
-
}
|
|
1388
|
-
catch (error) {
|
|
1389
|
-
CodeSolverSDK.handleError(error);
|
|
1390
|
-
return false;
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
/**
|
|
1394
|
-
* Отключается от WebSocket сервера
|
|
1395
|
-
* @returns {Promise<void>} Promise без результата
|
|
1396
|
-
*/
|
|
1397
|
-
async disconnect() {
|
|
1398
|
-
if (this.wsClient) {
|
|
1399
|
-
await this.wsClient.disconnectAll();
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
/**
|
|
1403
|
-
* Проверяет, подключен ли SDK к WebSocket серверу
|
|
1404
|
-
* @returns {boolean} Статус подключения
|
|
1405
|
-
*/
|
|
1406
|
-
isConnected() {
|
|
1407
|
-
if (!this.wsClient)
|
|
1408
|
-
return false;
|
|
1409
|
-
return this.wsClient.isConnectedToReasoning() || this.wsClient.isConnectedToIndexing();
|
|
1410
|
-
}
|
|
1411
|
-
/**
|
|
1412
|
-
* Проверяет доступность API (алиас для checkHealth)
|
|
1413
|
-
* @returns {Promise<boolean>} Promise с результатом проверки
|
|
1414
|
-
*/
|
|
1415
|
-
async isHealthy() {
|
|
1416
|
-
return this.checkHealth();
|
|
1417
|
-
}
|
|
1418
|
-
/**
|
|
1419
|
-
* Проверяет доступность всех сервисов API
|
|
1420
|
-
* @returns {Promise<{[key: string]: boolean}>} Статус каждого сервиса
|
|
1421
|
-
*/
|
|
1422
|
-
async checkServices() {
|
|
1423
|
-
try {
|
|
1424
|
-
const results = {
|
|
1425
|
-
api: false,
|
|
1426
|
-
websocket: false,
|
|
1427
|
-
database: false,
|
|
1428
|
-
search: false
|
|
1429
|
-
};
|
|
1430
|
-
try {
|
|
1431
|
-
// Проверка API
|
|
1432
|
-
results.api = await this.checkHealth();
|
|
1433
|
-
// Проверка других компонентов через запрос статуса
|
|
1434
|
-
const response = await this.httpClient.get('/api/v1/status');
|
|
1435
|
-
if (response && typeof response === 'object') {
|
|
1436
|
-
results.database = Boolean(response.database?.connected);
|
|
1437
|
-
results.search = Boolean(response.search?.connected);
|
|
1438
|
-
// Проверка WebSocket соединения
|
|
1439
|
-
if (this.wsClient) {
|
|
1440
|
-
results.websocket = this.wsClient.isConnectedToReasoning() ||
|
|
1441
|
-
this.wsClient.isConnectedToIndexing();
|
|
1442
|
-
}
|
|
1443
|
-
else {
|
|
1444
|
-
try {
|
|
1445
|
-
const wsClient = this.getWebSocketClient();
|
|
1446
|
-
await wsClient.connectToReasoning();
|
|
1447
|
-
results.websocket = true;
|
|
1448
|
-
await wsClient.disconnect(WebSocketNamespace.REASONING);
|
|
1449
|
-
}
|
|
1450
|
-
catch (e) {
|
|
1451
|
-
results.websocket = false;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
catch (error) {
|
|
1457
|
-
// Игнорируем ошибки при проверке
|
|
1458
|
-
}
|
|
1459
|
-
return results;
|
|
1460
|
-
}
|
|
1461
|
-
catch (error) {
|
|
1462
|
-
return {
|
|
1463
|
-
api: false,
|
|
1464
|
-
websocket: false,
|
|
1465
|
-
database: false,
|
|
1466
|
-
search: false
|
|
1467
|
-
};
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
/**
|
|
1471
|
-
* Закрывает соединение с сервером (алиас для dispose)
|
|
1472
|
-
*/
|
|
1473
|
-
close() {
|
|
1474
|
-
this.dispose();
|
|
1475
|
-
return Promise.resolve();
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
/** Глобальный обработчик ошибок */
|
|
1479
|
-
CodeSolverSDK.errorHandler = null;
|
|
1480
|
-
|
|
1481
|
-
// В браузере будем использовать нативный EventSource или полифилл
|
|
1482
|
-
const BrowserEventSource = typeof EventSource !== 'undefined' ? EventSource : EventSourcePolyfill;
|
|
1483
|
-
// Проверяем, находимся ли мы в браузере
|
|
1484
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
1485
|
-
/**
|
|
1486
|
-
* Клиент для работы с Server-Sent Events (SSE)
|
|
1487
|
-
* Поддерживает работу как в браузере, так и в Node.js
|
|
1488
|
-
*/
|
|
1489
|
-
class SseClient {
|
|
1490
|
-
/**
|
|
1491
|
-
* Создает новый SSE клиент
|
|
1492
|
-
* @param {string} url URL для подключения
|
|
1493
|
-
* @param {SseClientOptions} [options] Опции клиента
|
|
1494
|
-
*/
|
|
1495
|
-
constructor(url, options = {}) {
|
|
1496
|
-
/** Экземпляр EventSource */
|
|
1497
|
-
this.eventSource = null;
|
|
1498
|
-
/** Счетчик попыток переподключения */
|
|
1499
|
-
this.retryCount = 0;
|
|
1500
|
-
/** Флаг, указывающий, что соединение было закрыто намеренно */
|
|
1501
|
-
this.intentionallyClosed = false;
|
|
1502
|
-
/** Таймер переподключения */
|
|
1503
|
-
this.reconnectTimer = null;
|
|
1504
|
-
/** Таймер таймаута соединения */
|
|
1505
|
-
this.connectionTimeoutTimer = null;
|
|
1506
|
-
/** Обработчики событий */
|
|
1507
|
-
this.eventHandlers = {};
|
|
1508
|
-
this.url = url;
|
|
1509
|
-
this.options = {
|
|
1510
|
-
headers: options.headers || {},
|
|
1511
|
-
connectionTimeout: options.connectionTimeout || 30000,
|
|
1512
|
-
maxRetries: options.maxRetries || 5,
|
|
1513
|
-
retryDelay: options.retryDelay || 1000,
|
|
1514
|
-
maxRetryDelay: options.maxRetryDelay || 30000
|
|
1515
|
-
};
|
|
1516
|
-
}
|
|
1517
|
-
/**
|
|
1518
|
-
* Подключается к SSE эндпоинту
|
|
1519
|
-
* @returns {Promise<void>}
|
|
1520
|
-
*/
|
|
1521
|
-
connect() {
|
|
1522
|
-
// Если соединение уже установлено, возвращаем Promise.resolve
|
|
1523
|
-
if (this.eventSource && this.eventSource.readyState === 1) {
|
|
1524
|
-
return Promise.resolve();
|
|
1525
|
-
}
|
|
1526
|
-
// Сбрасываем флаг намеренного закрытия
|
|
1527
|
-
this.intentionallyClosed = false;
|
|
1528
|
-
return new Promise((resolve, reject) => {
|
|
1529
|
-
try {
|
|
1530
|
-
// Создаем новый экземпляр EventSource
|
|
1531
|
-
const EventSourceImpl = isBrowser ? BrowserEventSource : require('eventsource');
|
|
1532
|
-
this.eventSource = new EventSourceImpl(this.url, {
|
|
1533
|
-
headers: this.options.headers,
|
|
1534
|
-
withCredentials: true
|
|
1535
|
-
});
|
|
1536
|
-
// Устанавливаем таймаут соединения
|
|
1537
|
-
this.connectionTimeoutTimer = setTimeout(() => {
|
|
1538
|
-
if (this.eventSource && this.eventSource.readyState !== 1) {
|
|
1539
|
-
reject(new Error('Таймаут подключения SSE'));
|
|
1540
|
-
this.close();
|
|
1541
|
-
}
|
|
1542
|
-
}, this.options.connectionTimeout);
|
|
1543
|
-
// Проверяем, что this.eventSource не null
|
|
1544
|
-
if (!this.eventSource) {
|
|
1545
|
-
reject(new Error('Не удалось создать EventSource'));
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
// Обработчик открытия соединения
|
|
1549
|
-
this.eventSource.onopen = () => {
|
|
1550
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
1551
|
-
this.retryCount = 0;
|
|
1552
|
-
resolve();
|
|
1553
|
-
this.dispatchEvent('open', {});
|
|
1554
|
-
};
|
|
1555
|
-
// Обработчик сообщений
|
|
1556
|
-
this.eventSource.onmessage = (event) => {
|
|
1557
|
-
try {
|
|
1558
|
-
const data = JSON.parse(event.data);
|
|
1559
|
-
this.dispatchEvent('message', data);
|
|
1560
|
-
// Также вызываем специальный обработчик для конкретного типа события,
|
|
1561
|
-
// если такой тип указан в данных
|
|
1562
|
-
if (data && data.type) {
|
|
1563
|
-
this.dispatchEvent(data.type, data);
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
catch (error) {
|
|
1567
|
-
this.dispatchEvent('error', { error, message: 'Ошибка при обработке сообщения SSE' });
|
|
1568
|
-
}
|
|
1569
|
-
};
|
|
1570
|
-
// Обработчик ошибок
|
|
1571
|
-
this.eventSource.onerror = (error) => {
|
|
1572
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
1573
|
-
if (this.intentionallyClosed) {
|
|
1574
|
-
return;
|
|
1575
|
-
}
|
|
1576
|
-
// Если соединение уже установлено и произошла ошибка, просто сообщаем об ошибке
|
|
1577
|
-
if (this.eventSource && this.eventSource.readyState === 1) {
|
|
1578
|
-
this.dispatchEvent('error', { error, message: 'Ошибка SSE соединения' });
|
|
1579
|
-
return;
|
|
1580
|
-
}
|
|
1581
|
-
// Если это первая попытка подключения, отклоняем Promise
|
|
1582
|
-
if (this.retryCount === 0) {
|
|
1583
|
-
reject(new Error('Ошибка подключения SSE'));
|
|
1584
|
-
}
|
|
1585
|
-
// Запускаем процесс переподключения
|
|
1586
|
-
this.reconnect();
|
|
1587
|
-
};
|
|
1588
|
-
// Настраиваем обработчики для всех добавленных событий
|
|
1589
|
-
for (const eventType in this.eventHandlers) {
|
|
1590
|
-
if (eventType !== 'message' && eventType !== 'open' && eventType !== 'error') {
|
|
1591
|
-
this.eventSource.addEventListener(eventType, (event) => {
|
|
1592
|
-
try {
|
|
1593
|
-
const data = JSON.parse(event.data);
|
|
1594
|
-
this.dispatchEvent(eventType, data);
|
|
1595
|
-
}
|
|
1596
|
-
catch (e) {
|
|
1597
|
-
this.dispatchEvent(eventType, event.data);
|
|
1598
|
-
}
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
}
|
|
1603
|
-
catch (error) {
|
|
1604
|
-
reject(error);
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1607
|
-
}
|
|
1608
|
-
/**
|
|
1609
|
-
* Закрывает SSE соединение
|
|
1610
|
-
*/
|
|
1611
|
-
close() {
|
|
1612
|
-
this.intentionallyClosed = true;
|
|
1613
|
-
// Очищаем таймеры
|
|
1614
|
-
clearTimeout(this.reconnectTimer);
|
|
1615
|
-
clearTimeout(this.connectionTimeoutTimer);
|
|
1616
|
-
// Закрываем соединение
|
|
1617
|
-
if (this.eventSource) {
|
|
1618
|
-
this.eventSource.close();
|
|
1619
|
-
this.eventSource = null;
|
|
1620
|
-
}
|
|
1621
|
-
this.dispatchEvent('close', {});
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Добавляет обработчик события
|
|
1625
|
-
* @param {string} eventType Тип события
|
|
1626
|
-
* @param {SseEventHandler} handler Обработчик события
|
|
1627
|
-
*/
|
|
1628
|
-
on(eventType, handler) {
|
|
1629
|
-
if (!this.eventHandlers[eventType]) {
|
|
1630
|
-
this.eventHandlers[eventType] = [];
|
|
1631
|
-
// Если соединение уже установлено, добавляем обработчик события
|
|
1632
|
-
if (this.eventSource && this.eventSource.readyState === 1 &&
|
|
1633
|
-
eventType !== 'message' && eventType !== 'open' && eventType !== 'error') {
|
|
1634
|
-
this.eventSource.addEventListener(eventType, (event) => {
|
|
1635
|
-
try {
|
|
1636
|
-
const data = JSON.parse(event.data);
|
|
1637
|
-
this.dispatchEvent(eventType, data);
|
|
1638
|
-
}
|
|
1639
|
-
catch (e) {
|
|
1640
|
-
this.dispatchEvent(eventType, event.data);
|
|
1641
|
-
}
|
|
1642
|
-
});
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
this.eventHandlers[eventType].push(handler);
|
|
1646
|
-
}
|
|
1647
|
-
/**
|
|
1648
|
-
* Удаляет обработчик события
|
|
1649
|
-
* @param {string} eventType Тип события
|
|
1650
|
-
* @param {SseEventHandler} [handler] Обработчик события (если не указан, удаляются все обработчики)
|
|
1651
|
-
*/
|
|
1652
|
-
off(eventType, handler) {
|
|
1653
|
-
if (!this.eventHandlers[eventType]) {
|
|
1654
|
-
return;
|
|
1655
|
-
}
|
|
1656
|
-
if (!handler) {
|
|
1657
|
-
// Если обработчик не указан, удаляем все обработчики для данного события
|
|
1658
|
-
delete this.eventHandlers[eventType];
|
|
1659
|
-
}
|
|
1660
|
-
else {
|
|
1661
|
-
// Если обработчик указан, удаляем только его
|
|
1662
|
-
this.eventHandlers[eventType] = this.eventHandlers[eventType].filter(h => h !== handler);
|
|
1663
|
-
// Если обработчиков больше нет, удаляем массив
|
|
1664
|
-
if (this.eventHandlers[eventType].length === 0) {
|
|
1665
|
-
delete this.eventHandlers[eventType];
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
/**
|
|
1670
|
-
* Вызывает обработчики для указанного события
|
|
1671
|
-
* @param {string} eventType Тип события
|
|
1672
|
-
* @param {any} data Данные события
|
|
1673
|
-
*/
|
|
1674
|
-
dispatchEvent(eventType, data) {
|
|
1675
|
-
if (!this.eventHandlers[eventType]) {
|
|
1676
|
-
return;
|
|
1677
|
-
}
|
|
1678
|
-
for (const handler of this.eventHandlers[eventType]) {
|
|
1679
|
-
try {
|
|
1680
|
-
handler(data);
|
|
1681
|
-
}
|
|
1682
|
-
catch (e) {
|
|
1683
|
-
console.error(`Ошибка в обработчике события ${eventType}:`, e);
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
/**
|
|
1688
|
-
* Переподключается к SSE эндпоинту с экспоненциальной задержкой
|
|
1689
|
-
* @private
|
|
1690
|
-
*/
|
|
1691
|
-
reconnect() {
|
|
1692
|
-
// Увеличиваем счетчик попыток
|
|
1693
|
-
this.retryCount++;
|
|
1694
|
-
// Если превышено максимальное количество попыток, прекращаем
|
|
1695
|
-
if (this.retryCount > (this.options.maxRetries || 5)) {
|
|
1696
|
-
this.dispatchEvent('maxRetries', { retries: this.retryCount });
|
|
1697
|
-
return;
|
|
1698
|
-
}
|
|
1699
|
-
// Вычисляем задержку перед переподключением с экспоненциальным ростом
|
|
1700
|
-
const delay = Math.min((this.options.retryDelay || 1000) * Math.pow(2, this.retryCount - 1), this.options.maxRetryDelay || 30000);
|
|
1701
|
-
// Пытаемся переподключиться после задержки
|
|
1702
|
-
this.reconnectTimer = setTimeout(() => {
|
|
1703
|
-
this.dispatchEvent('reconnect', { attempt: this.retryCount });
|
|
1704
|
-
this.connect().catch(() => { });
|
|
1705
|
-
}, delay);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
/**
|
|
1710
|
-
* События индексации
|
|
1711
|
-
*/
|
|
1712
|
-
var IndexingEvent;
|
|
1713
|
-
(function (IndexingEvent) {
|
|
1714
|
-
/** Начало индексации */
|
|
1715
|
-
IndexingEvent["START"] = "indexing_start";
|
|
1716
|
-
/** Прогресс индексации */
|
|
1717
|
-
IndexingEvent["PROGRESS"] = "indexing_progress";
|
|
1718
|
-
/** Завершение индексации */
|
|
1719
|
-
IndexingEvent["COMPLETE"] = "indexing_complete";
|
|
1720
|
-
/** Ошибка индексации */
|
|
1721
|
-
IndexingEvent["ERROR"] = "indexing_error";
|
|
1722
|
-
})(IndexingEvent || (IndexingEvent = {}));
|
|
1723
|
-
/**
|
|
1724
|
-
* WebSocket клиент для работы с индексацией
|
|
1725
|
-
*/
|
|
1726
|
-
class IndexingWebSocketClient extends WebSocketClient {
|
|
1727
|
-
/**
|
|
1728
|
-
* Создает новый WebSocket клиент для индексации
|
|
1729
|
-
* @param {string} url URL для подключения
|
|
1730
|
-
* @param {IndexingWebSocketOptions} [options] Опции клиента
|
|
1731
|
-
*/
|
|
1732
|
-
constructor(url, options = {}) {
|
|
1733
|
-
// Сохраняем базовый URL
|
|
1734
|
-
const baseUrl = url;
|
|
1735
|
-
// Формируем URL с параметрами для проекта если он указан
|
|
1736
|
-
let targetUrl = url;
|
|
1737
|
-
if (options.projectId) {
|
|
1738
|
-
const urlWithParams = new URL(url);
|
|
1739
|
-
urlWithParams.searchParams.append('projectId', options.projectId);
|
|
1740
|
-
urlWithParams.searchParams.append('type', 'indexing');
|
|
1741
|
-
targetUrl = urlWithParams.toString();
|
|
1742
|
-
}
|
|
1743
|
-
super(targetUrl, {
|
|
1744
|
-
...options,
|
|
1745
|
-
headers: {
|
|
1746
|
-
...(options.headers || {}),
|
|
1747
|
-
...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {})
|
|
1748
|
-
}
|
|
1749
|
-
});
|
|
1750
|
-
/** Идентификатор проекта */
|
|
1751
|
-
this.projectId = null;
|
|
1752
|
-
this.baseUrl = baseUrl;
|
|
1753
|
-
this.projectId = options.projectId || null;
|
|
1754
|
-
}
|
|
1755
|
-
/**
|
|
1756
|
-
* Устанавливает идентификатор проекта
|
|
1757
|
-
* @param {string} projectId Идентификатор проекта
|
|
1758
|
-
*/
|
|
1759
|
-
setProjectId(projectId) {
|
|
1760
|
-
this.projectId = projectId;
|
|
1761
|
-
}
|
|
1762
|
-
/**
|
|
1763
|
-
* Подключается к WebSocket для отслеживания индексации
|
|
1764
|
-
* @param {string} [projectId] Идентификатор проекта (если не был указан в конструкторе)
|
|
1765
|
-
* @returns {Promise<void>}
|
|
1766
|
-
*/
|
|
1767
|
-
async connect(projectId) {
|
|
1768
|
-
const targetProjectId = projectId || this.projectId;
|
|
1769
|
-
if (!targetProjectId) {
|
|
1770
|
-
throw new Error('Project ID is required for indexing WebSocket connection');
|
|
1771
|
-
}
|
|
1772
|
-
// Сохраняем ID проекта
|
|
1773
|
-
this.projectId = targetProjectId;
|
|
1774
|
-
// Если проект изменился и клиент уже подключен, отключаемся
|
|
1775
|
-
if (projectId && this.isConnected()) {
|
|
1776
|
-
this.close();
|
|
1777
|
-
}
|
|
1778
|
-
// Выполняем соединение
|
|
1779
|
-
await super.connect();
|
|
1780
|
-
}
|
|
1781
|
-
/**
|
|
1782
|
-
* Подписывается на события начала индексации
|
|
1783
|
-
* @param {(data: {projectId: string}) => void} handler Обработчик события
|
|
1784
|
-
*/
|
|
1785
|
-
onStart(handler) {
|
|
1786
|
-
this.on(IndexingEvent.START, handler);
|
|
1787
|
-
}
|
|
1788
|
-
/**
|
|
1789
|
-
* Подписывается на события прогресса индексации
|
|
1790
|
-
* @param {(data: IndexingProgressData) => void} handler Обработчик события
|
|
1791
|
-
*/
|
|
1792
|
-
onProgress(handler) {
|
|
1793
|
-
this.on(IndexingEvent.PROGRESS, handler);
|
|
1794
|
-
}
|
|
1795
|
-
/**
|
|
1796
|
-
* Подписывается на события завершения индексации
|
|
1797
|
-
* @param {(data: IndexingCompleteData) => void} handler Обработчик события
|
|
1798
|
-
*/
|
|
1799
|
-
onComplete(handler) {
|
|
1800
|
-
this.on(IndexingEvent.COMPLETE, handler);
|
|
1801
|
-
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Подписывается на события ошибок индексации
|
|
1804
|
-
* @param {(data: IndexingErrorData) => void} handler Обработчик события
|
|
1805
|
-
*/
|
|
1806
|
-
onError(handler) {
|
|
1807
|
-
this.on(IndexingEvent.ERROR, handler);
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
/**
|
|
1812
|
-
* Общие типы данных для SDK
|
|
1813
|
-
*/
|
|
1814
|
-
/**
|
|
1815
|
-
* Уровень логирования
|
|
1816
|
-
*/
|
|
1817
|
-
var LogLevel;
|
|
1818
|
-
(function (LogLevel) {
|
|
1819
|
-
LogLevel["DEBUG"] = "debug";
|
|
1820
|
-
LogLevel["INFO"] = "info";
|
|
1821
|
-
LogLevel["WARN"] = "warn";
|
|
1822
|
-
LogLevel["ERROR"] = "error";
|
|
1823
|
-
})(LogLevel || (LogLevel = {}));
|
|
1824
|
-
|
|
1825
1
|
// Экспорт основного класса SDK
|
|
2
|
+
export { CodeSolverSDK } from './code-solver-sdk.js';
|
|
3
|
+
// Экспорт API классов
|
|
4
|
+
export { ProjectsApi } from './api/projects-api.js';
|
|
5
|
+
export { SearchApi } from './api/search-api.js';
|
|
6
|
+
export { ReasoningApi } from './api/reasoning-api.js';
|
|
7
|
+
export { ContextApi } from './api/context-api.js';
|
|
8
|
+
export { CodeModificationApi } from './api/code-modification-api.js';
|
|
9
|
+
export { AgentsApi } from './api/agents-api.js';
|
|
10
|
+
// Экспорт утилит
|
|
11
|
+
export { HttpClient } from './utils/http-client.js';
|
|
12
|
+
export { SseClient } from './utils/sse-client.js';
|
|
13
|
+
export { WebSocketClient } from './utils/websocket-client.js';
|
|
14
|
+
export { IndexingWebSocketClient } from './utils/indexing-websocket-client.js';
|
|
15
|
+
export { CodeSolverWebSocketClient, WebSocketNamespace } from './utils/code-solver-websocket-client.js';
|
|
16
|
+
// Экспорт типов
|
|
17
|
+
export * from './models/types.js';
|
|
1826
18
|
// Версия SDK
|
|
1827
|
-
const VERSION = '1.0.0';
|
|
19
|
+
export const VERSION = '1.0.0';
|
|
20
|
+
// Экспорт по умолчанию для удобства использования
|
|
21
|
+
export { CodeSolverSDK as default } from './code-solver-sdk.js';
|
|
1828
22
|
// Простой пример использования SDK
|
|
1829
23
|
/**
|
|
1830
24
|
* Пример использования SDK:
|
|
@@ -1889,7 +83,5 @@ const VERSION = '1.0.0';
|
|
|
1889
83
|
* });
|
|
1890
84
|
* }
|
|
1891
85
|
* ```
|
|
1892
|
-
*/
|
|
1893
|
-
|
|
1894
|
-
export { AgentsApi, CodeModificationApi, CodeSolverSDK, CodeSolverWebSocketClient, ContextApi, HttpClient, IndexingWebSocketClient, LogLevel, ProjectsApi, ReasoningApi, SearchApi, SseClient, VERSION, WebSocketClient, WebSocketNamespace, CodeSolverSDK as default };
|
|
1895
|
-
//# sourceMappingURL=index.js.map
|
|
86
|
+
*/
|
|
87
|
+
//# sourceMappingURL=index.js.map
|