solver-sdk
Version:
SDK для интеграции с Code Solver Backend API
451 lines • 18.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeSolverSDK = void 0;
const http_client_js_1 = require("./utils/http-client.js");
const projects_api_js_1 = require("./api/projects-api.js");
const search_api_js_1 = require("./api/search-api.js");
const context_api_js_1 = require("./api/context-api.js");
const reasoning_api_js_1 = require("./api/reasoning-api.js");
const code_modification_api_js_1 = require("./api/code-modification-api.js");
const agents_api_js_1 = require("./api/agents-api.js");
const index_js_1 = require("./api/chat-api/index.js");
const models_api_js_1 = require("./api/models-api.js");
const dependencies_api_js_1 = require("./api/dependencies-api.js");
// Импорт пространств имен WebSocket
const websocket_namespaces_constants_js_1 = require("./constants/websocket-namespaces.constants.js");
// Версия SDK
const SDK_VERSION = '2.0.2';
// Импорт WebSocket клиентов
const indexing_ws_client_js_1 = require("./ws/indexing-ws-client.js");
const reasoning_ws_client_js_1 = require("./ws/reasoning-ws-client.js");
const filesystem_ws_client_js_1 = require("./ws/filesystem-ws-client.js");
const dependencies_ws_client_js_1 = require("./ws/dependencies-ws-client.js");
/**
* Определение типа среды выполнения
* @returns 'browser' | 'node' | 'unknown'
*/
function getEnvironment() {
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
return 'browser';
}
else if (typeof process !== 'undefined' && process.versions && process.versions.node) {
return 'node';
}
return 'unknown';
}
/**
* Основной класс SDK для работы с Code Solver API
* В версии 2.0 с современной архитектурой и без обратной совместимости
*/
class CodeSolverSDK {
/**
* Создает новый экземпляр SDK
* @param {CodeSolverSDKOptions} options Опции SDK
*/
constructor(options) {
/** WebSocket клиенты для разных пространств имен */
this._indexingClient = null;
this._reasoningClient = null;
this._fileSystemClient = null;
this._dependenciesClient = null;
/** Logger для внутреннего использования */
this.logger = {
log: (message) => {
if (this._options.debug) {
console.log(`[CodeSolverSDK] ${message}`);
}
},
warn: (message) => {
if (this._options.debug) {
console.warn(`[CodeSolverSDK] ⚠️ ${message}`);
}
},
error: (message) => {
console.error(`[CodeSolverSDK] 🔴 ${message}`);
},
debug: (message) => {
if (this._options.debug === 'verbose') {
console.debug(`[CodeSolverSDK] 🔍 ${message}`);
}
}
};
this._options = {
...options,
mode: options.mode || 'auto'
};
// Определяем среду выполнения
this.environment = this._options.mode === 'auto'
? getEnvironment()
: this._options.mode === 'browser' ? 'browser' : 'node';
// Инициализируем HTTP клиент
this.httpClient = new http_client_js_1.HttpClient(this._options.baseURL, {
headers: {
...(this._options.apiKey ? { 'Authorization': `Bearer ${this._options.apiKey}` } : {}),
...(this._options.headers || {})
},
timeout: this._options.timeout,
httpsAgent: this.environment === 'node' ? this._options.httpsAgent : undefined
});
// Инициализируем API клиенты
this._projects = new projects_api_js_1.ProjectsApi(this.httpClient);
this._search = new search_api_js_1.SearchApi(this.httpClient);
this._reasoning = new reasoning_api_js_1.ReasoningApi(this.httpClient, this._projects);
this._context = new context_api_js_1.ContextApi(this.httpClient, this._projects);
this._codeModification = new code_modification_api_js_1.CodeModificationApi(this.httpClient);
this._agents = new agents_api_js_1.AgentsApi(this.httpClient);
this._chat = new index_js_1.ChatApi(this.httpClient);
this._models = new models_api_js_1.ModelsApi(this.httpClient);
this._dependencies = new dependencies_api_js_1.DependenciesApi(this.httpClient);
// Устанавливаем ссылку на SDK для API классов, поддерживающих WebSocket
if (typeof this._projects.setParent === 'function') {
this._projects.setParent(this);
}
if (typeof this._reasoning.setParent === 'function') {
this._reasoning.setParent(this);
}
if (typeof this._dependencies.setParent === 'function') {
this._dependencies.setParent(this);
}
}
/**
* Проверяет доступность API
* @returns {Promise<boolean>} Доступен ли API
*/
async checkHealth() {
try {
await this.httpClient.get('/health');
return true;
}
catch (error) {
return false;
}
}
/**
* Получает WebSocket URL
* @private
*/
get wsURL() {
let url = this._options.baseURL || '';
// Заменяем протокол HTTP на WS
if (url.startsWith('http://')) {
url = url.replace('http://', 'ws://');
}
else if (url.startsWith('https://')) {
url = url.replace('https://', 'wss://');
}
return url;
}
/**
* Получает конфигурацию WebSocket
* @private
*/
get wsConfig() {
return this._options.websocket || {};
}
/**
* Получает клиент для индексации
* @returns {IndexingWebSocketClient} Клиент для индексации
*/
getIndexingClient() {
if (!this._indexingClient) {
const wsURL = this.wsURL;
this._indexingClient = new indexing_ws_client_js_1.IndexingWebSocketClient(wsURL, {
apiKey: this._options.apiKey,
headers: this._options.headers,
autoReconnect: this.wsConfig.reconnect !== false,
maxRetries: this.wsConfig.reconnectAttempts || 5,
retryDelay: this.wsConfig.reconnectDelay || 1000,
rejectUnauthorized: this.wsConfig.rejectUnauthorized
});
}
return this._indexingClient;
}
/**
* Получает клиент для рассуждений
* @returns {ReasoningWebSocketClient} Клиент для рассуждений
*/
getReasoningClient() {
if (!this._reasoningClient) {
const wsURL = this.wsURL;
this._reasoningClient = new reasoning_ws_client_js_1.ReasoningWebSocketClient(wsURL, {
apiKey: this._options.apiKey,
headers: this._options.headers,
autoReconnect: this.wsConfig.reconnect !== false,
maxRetries: this.wsConfig.reconnectAttempts || 5,
retryDelay: this.wsConfig.reconnectDelay || 1000,
rejectUnauthorized: this.wsConfig.rejectUnauthorized,
callbacks: {} // Инициализируем пустой объект callbacks
});
}
return this._reasoningClient;
}
/**
* Получает клиент для работы с файловой системой
* @param {Partial<FileSystemWsClientOptions>} options Опции клиента файловой системы
* @returns {FileSystemWsClient} Клиент для работы с файловой системой
*/
getFileSystemClient(options = {}) {
if (!this._fileSystemClient) {
const wsURL = this.wsURL;
this._fileSystemClient = new filesystem_ws_client_js_1.FileSystemWsClient(wsURL, {
onReadFile: options.onReadFile,
onListFiles: options.onListFiles,
onWatchStart: options.onWatchStart
});
}
return this._fileSystemClient;
}
/**
* Получает клиент для работы с зависимостями
* @returns {DependenciesWsClient} Клиент для работы с зависимостями
*/
getDependenciesClient() {
if (!this._dependenciesClient) {
const wsURL = this.wsURL;
this._dependenciesClient = new dependencies_ws_client_js_1.DependenciesWsClient(websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES, wsURL, {
apiKey: this._options.apiKey,
headers: this._options.headers,
autoReconnect: this.wsConfig.reconnect !== false,
maxRetries: this.wsConfig.reconnectAttempts || 5,
retryDelay: this.wsConfig.reconnectDelay || 1000,
rejectUnauthorized: this.wsConfig.rejectUnauthorized
});
}
return this._dependenciesClient;
}
/**
* Закрывает все WebSocket соединения
*/
disconnectAll() {
if (this._indexingClient) {
this._indexingClient.disconnect();
}
if (this._reasoningClient) {
this._reasoningClient.disconnect();
}
if (this._fileSystemClient) {
this._fileSystemClient.disconnect();
}
if (this._dependenciesClient) {
this._dependenciesClient.disconnect();
}
}
/**
* API для работы с агентами
*/
get agents() {
return this._agents;
}
/**
* API для работы с контекстом
*/
get context() {
return this._context;
}
/**
* API для работы с проектами
*/
get projects() {
return this._projects;
}
/**
* API для поиска кода
*/
get search() {
return this._search;
}
/**
* API для работы с рассуждениями
*/
get reasoning() {
return this._reasoning;
}
/**
* API для модификации кода
*/
get codeModification() {
return this._codeModification;
}
/**
* Возвращает API для работы с чатом
* @returns {ChatApi} API для работы с чатом
*/
get chat() {
return this._chat;
}
/**
* API для работы с моделями
*/
get models() {
return this._models;
}
/**
* API для работы с зависимостями
*/
get dependencies() {
return this._dependencies;
}
/**
* Настраивает обработчики событий Anthropic API
* @param {ReasoningWebSocketClient} reasoningClient WebSocket клиент для рассуждений
* @param {AnthropicStreamCallbacks} callbacks Коллбэки для обработки событий
* @private
*/
setupAnthropicEventHandlers(reasoningClient, callbacks) {
// Устанавливаем все обработчики для клиента рассуждений
reasoningClient.setupAnthropicStreamHandlers();
// Устанавливаем внешние обработчики
if (callbacks) {
reasoningClient.callbacks = callbacks;
}
}
/**
* Выполняет запрос к API для генерации рассуждения с использованием Anthropic API
* с поддержкой потоковой передачи данных через WebSocket
*
* @param {ExtendedReasoningOptions} options Опции для рассуждения
* @param {AnthropicStreamCallbacks} callbacks Коллбэки для обработки событий
* @returns {Promise<void>} Promise без результата
*/
async executeReasoning(options, callbacks) {
try {
// Проверяем, что все необходимые параметры указаны
if (!options.projectId) {
throw new Error('Не указан projectId для выполнения рассуждения');
}
// Подключаемся к WebSocket серверу если еще не подключены
const reasoningClient = this.getReasoningClient();
if (!reasoningClient.isConnected()) {
await reasoningClient.connectToReasoning();
}
// Подписываемся на события
this.setupAnthropicEventHandlers(reasoningClient, callbacks);
// Отправляем запрос на выполнение рассуждения
await reasoningClient.emitWithAck('create_reasoning', {
projectId: options.projectId,
request: {
prompt: options.query,
options: {
streamMode: true,
planningMode: Boolean(options.thinking),
modelName: options.model || 'claude-3-sonnet'
}
}
});
}
catch (error) {
this.logger.error(`Ошибка при отправке запроса на рассуждение: ${error instanceof Error ? error.message : String(error)}`);
callbacks.onError?.({
code: 'SDK_ERROR',
message: `Ошибка при отправке запроса: ${error instanceof Error ? error.message : String(error)}`
});
throw error;
}
}
/**
* Подключается к WebSocket серверу
* @returns {Promise<boolean>} Promise с результатом подключения
*/
async connect() {
try {
// Подключаемся к различным пространствам имен
await this.getIndexingClient().connect();
await this.getReasoningClient().connect();
await this.getFileSystemClient().connect();
await this.getDependenciesClient().connect();
return true;
}
catch (error) {
CodeSolverSDK.handleError(error);
return false;
}
}
/**
* Проверяет, подключен ли SDK к WebSocket серверу
* @returns {boolean} Статус подключения
*/
isConnected() {
if (!this._indexingClient && !this._reasoningClient && !this._fileSystemClient && !this._dependenciesClient) {
return false;
}
const indexingConnected = this._indexingClient?.isConnected() || false;
const reasoningConnected = this._reasoningClient?.isConnected() || false;
const fileSystemConnected = this._fileSystemClient?.isConnected() || false;
const dependenciesConnected = this._dependenciesClient?.isConnected() || false;
return indexingConnected || reasoningConnected || fileSystemConnected || dependenciesConnected;
}
/**
* Обрабатывает ошибку
* @param {Error} error Объект ошибки
*/
static handleError(error) {
if (CodeSolverSDK.errorHandler) {
CodeSolverSDK.errorHandler(error);
}
else {
console.error('[CodeSolverSDK] Необработанная ошибка:', error);
}
}
/**
* Устанавливает глобальный обработчик ошибок
* @param {(error: Error) => void} handler Обработчик ошибок
*/
static setErrorHandler(handler) {
CodeSolverSDK.errorHandler = handler;
}
/**
* Очищает все ресурсы
*/
dispose() {
this.disconnectAll();
}
/**
* Устанавливает новый API ключ
* @param {string} apiKey Новый API ключ
*/
setApiKey(apiKey) {
// Обновляем API ключ в опциях
this._options.apiKey = apiKey;
// Пересоздаем HTTP клиент с новым API ключом
const newHttpClient = new http_client_js_1.HttpClient(this._options.baseURL, {
headers: {
...(apiKey ? { 'Authorization': `Bearer ${apiKey}` } : {}),
...(this._options.headers || {})
},
timeout: this._options.timeout,
httpsAgent: this.environment === 'node' ? this._options.httpsAgent : undefined
});
// Обновляем API клиенты с новым HTTP клиентом
this.httpClient = newHttpClient;
this._projects = new projects_api_js_1.ProjectsApi(newHttpClient);
this._search = new search_api_js_1.SearchApi(newHttpClient);
this._reasoning = new reasoning_api_js_1.ReasoningApi(newHttpClient, this._projects);
this._context = new context_api_js_1.ContextApi(newHttpClient, this._projects);
this._codeModification = new code_modification_api_js_1.CodeModificationApi(newHttpClient);
this._agents = new agents_api_js_1.AgentsApi(newHttpClient);
this._chat = new index_js_1.ChatApi(newHttpClient);
this._models = new models_api_js_1.ModelsApi(newHttpClient);
this._dependencies = new dependencies_api_js_1.DependenciesApi(newHttpClient);
// Если есть WebSocket клиенты, пересоздаем их
if (this._indexingClient) {
this._indexingClient.disconnect();
this._indexingClient = null;
}
if (this._reasoningClient) {
this._reasoningClient.disconnect();
this._reasoningClient = null;
}
if (this._fileSystemClient) {
this._fileSystemClient.disconnect();
this._fileSystemClient = null;
}
if (this._dependenciesClient) {
this._dependenciesClient.disconnect();
this._dependenciesClient = null;
}
}
}
exports.CodeSolverSDK = CodeSolverSDK;
/** Глобальный обработчик ошибок */
CodeSolverSDK.errorHandler = null;
//# sourceMappingURL=code-solver-sdk.js.map