solver-sdk
Version:
SDK для интеграции с Code Solver Backend API (совместимо с браузером и Node.js), с поддержкой функциональности мышления (Thinking Mode)
508 lines (401 loc) • 20.3 kB
Markdown
# Работа с WebSocket соединениями
В этом разделе описаны возможности SDK для работы с WebSocket соединениями, методы управления сессиями рассуждений, диагностика соединений и дополнительные возможности для обеспечения стабильной работы.
## Содержание
- [Основы работы с WebSocket](#основы-работы-с-websocket)
- [Высокоуровневый API (версия 1.7.2)](#высокоуровневый-api-версия-172)
- [Потоковая передача мышления](#потоковая-передача-мышления)
- [Управление сессиями рассуждений](#управление-сессиями-рассуждений)
- [Диагностика соединений](#диагностика-соединений)
- [Механизм переподключения](#механизм-переподключения)
- [Сохранение и восстановление сессий](#сохранение-и-восстановление-сессий)
- [Проверка здоровья соединений](#проверка-здоровья-соединений)
- [Работа с ping/pong](#работа-с-pingpong)
- [Примеры использования](#примеры-использования)
- [Справочник всех событий WebSocket](#справочник-всех-событий-websocket)
## Основы работы с WebSocket
SDK предоставляет низкоуровневый WebSocket клиент (`CodeSolverWebSocketClient`), который используется для связи с различными пространствами имен сервера:
```javascript
const { CodeSolverSDK } = require('solver-sdk');
const sdk = new CodeSolverSDK({
baseURL: 'https://api.example.com',
apiKey: 'your-api-key'
});
// Получение WebSocket клиента
const wsClient = sdk.getWebSocketClient();
// Подключение к пространству имен рассуждений
await wsClient.connectToReasoning('reasoning-id');
// Проверка состояния подключения
const isConnected = wsClient.isConnectedToReasoning();
console.log('Подключено к рассуждениям:', isConnected);
// Подписка на события
wsClient.on('thinking_delta', (data) => {
console.log('Получен фрагмент мышления:', data.text);
});
// Отключение
wsClient.disconnect(WebSocketNamespace.REASONING);
```
## Высокоуровневый API (версия 1.7.2)
Начиная с версии 1.7.2, SDK предоставляет высокоуровневый API для работы с WebSocket, интегрированный непосредственно в основные классы API:
### Работа с чатом и рассуждениями
```javascript
// Подключение WebSocket для чата
await sdk.chat.connectWebSocket();
// Подписка на события
sdk.chat.on('message_start', (data) => {
console.log('Начало сообщения:', data);
});
sdk.chat.on('thinking_delta', (data) => {
console.log('Фрагмент мышления:', data.text);
});
// Отключение
await sdk.chat.disconnectWebSocket();
```
### Работа с зависимостями
```javascript
// Подключение к пространству имен зависимостей
await sdk.dependencies.connectWebSocket(projectId);
// Подписка на события зависимостей
sdk.dependencies.on('dependency_update', (data) => {
console.log('Обновление зависимостей:', data);
});
// Отключение
await sdk.dependencies.disconnectWebSocket();
```
### Работа с проектами и индексацией
```javascript
// Подключение к пространству имен проектов
await sdk.projects.connectWebSocket();
// Подписка на события индексации
sdk.projects.on('indexing_progress', (data) => {
console.log('Прогресс индексации:', data.progress);
});
// Отключение
await sdk.projects.disconnectWebSocket();
```
## Потоковая передача мышления
В версии 1.7.2 добавлена полная поддержка потоковой передачи мышления через метод `streamChatWithThinking`:
```javascript
// Обработчик событий
const handleEvent = (eventType, data) => {
switch(eventType) {
case 'thinking_delta':
console.log('Мышление:', data.text);
break;
case 'text_delta':
console.log('Ответ:', data.text);
break;
case 'message_start':
console.log('Начало сообщения');
break;
case 'message_stop':
console.log('Завершение ответа');
break;
}
};
// Отправка запроса с потоковым мышлением
const messages = [
{ role: 'user', content: 'Как работает квантовый компьютер?' }
];
const options = {
model: 'claude-3-7-sonnet-20240229',
thinking: true,
temperature: 0.7
};
const response = await sdk.chat.streamChatWithThinking(
messages,
options,
handleEvent
);
```
### Поддерживаемые события мышления
SDK поддерживает следующие ключевые события:
| Событие | Описание | Данные |
|---------|----------|--------|
| `message_start` | Начало сообщения | `{ model: string, type: string }` |
| `content_block_start` | Начало блока контента | `{ index: number, type: string }` |
| `thinking_delta` | Фрагмент мышления | `{ text: string, index: number }` |
| `text_delta` | Фрагмент ответа | `{ text: string, index: number }` |
| `content_block_stop` | Завершение блока контента | `{ index: number, type: string }` |
| `message_stop` | Завершение сообщения | `{ type: string }` |
## Управление сессиями рассуждений
SDK версии 1.7.0+ предоставляет расширенные возможности для управления сессиями рассуждений:
### Установка активной сессии рассуждения
```javascript
// Простая установка активного ID рассуждения
wsClient.setActiveReasoningId('reasoning-id');
// Расширенный вариант с дополнительными возможностями
await wsClient.setActiveReasoningIdAsync(
'reasoning-id', // ID рассуждения (можно передать null для создания нового)
true, // waitForJoin: ждать результата присоединения
true // createIfNotExists: создать новое, если не существует
);
```
### Создание нового рассуждения
```javascript
// Создание нового рассуждения и получение его ID
const newReasoningId = await wsClient.createNewReasoning();
console.log('Создано новое рассуждение:', newReasoningId);
```
### Проверка существования рассуждения
```javascript
// Проверка существования рассуждения на сервере
const exists = await wsClient.checkReasoningExists('reasoning-id');
if (exists) {
console.log('Рассуждение существует');
} else {
console.log('Рассуждение не найдено');
}
```
### Получение статуса рассуждения
```javascript
// Получение детальной информации о сессии рассуждения
const status = await wsClient.getReasoningStatus('reasoning-id');
console.log('Статус:', status.exists, status.isActive);
console.log('Метаданные:', status.metadata);
```
### Присоединение к сессии рассуждения
```javascript
// Явное присоединение к существующей сессии
const joined = await wsClient.joinReasoning(
'reasoning-id',
true // setActive: установить как активное рассуждение
);
if (joined) {
console.log('Успешно присоединились к рассуждению');
} else {
console.log('Не удалось присоединиться к рассуждению');
}
```
## Диагностика соединений
SDK предоставляет методы для диагностики состояния соединений и получения подробной информации о них:
```javascript
// Диагностика конкретного соединения
const diagnostics = wsClient.diagnoseConnection(WebSocketNamespace.REASONING);
console.log('Диагностика соединения:', diagnostics);
// Диагностика всех активных соединений
const allDiagnostics = wsClient.diagnoseAllConnections();
console.log('Все соединения:', allDiagnostics);
```
Результат диагностики содержит следующую информацию:
```typescript
interface ConnectionDiagnostics {
namespace: WebSocketNamespace; // Пространство имен
isConnected: boolean; // Активно ли соединение
socketId: string | null; // ID сокета
lastActivity: number; // Время последней активности
rtt: { // Round Trip Time (задержка)
current: number; // Текущая задержка
min: number; // Минимальная задержка
max: number; // Максимальная задержка
avg: number; // Средняя задержка
};
pingSent: number; // Отправлено ping-сообщений
pongReceived: number; // Получено pong-ответов
missedPongs: number; // Пропущено pong-ответов
timeoutCount: number; // Количество таймаутов
reconnectAttempts: number; // Количество попыток переподключения
lastConnectTime: number; // Время последнего подключения
sessionRecovery: { // Информация о восстановлении сессии
hasSessionToken: boolean; // Наличие токена сессии
tokenLength: number; // Длина токена сессии
wasRecovered: boolean; // Было ли восстановлено из сессии
};
}
```
## Механизм переподключения
SDK реализует интеллектуальный механизм переподключения с экспоненциальной задержкой и случайным фактором (jitter) для предотвращения штормов переподключений:
```javascript
// Настройка параметров переподключения при создании SDK
const sdk = new CodeSolverSDK({
baseURL: 'https://api.example.com',
apiKey: 'your-api-key',
websocket: {
reconnect: true, // Включить автоматическое переподключение
reconnectStrategy: 'exponential', // 'linear' или 'exponential'
retryDelay: 1000, // Базовая задержка в миллисекундах
maxRetryDelay: 30000, // Максимальная задержка
reconnectAttempts: 5 // Максимальное количество попыток
}
});
// Принудительное переподключение к пространству имен
await wsClient.reconnectNamespace(
WebSocketNamespace.REASONING,
true // immediate: переподключиться немедленно, без задержки
);
```
## Сохранение и восстановление сессий
SDK поддерживает механизм сохранения и восстановления токенов сессий для непрерывной работы при переподключениях:
```javascript
// Явное сохранение токена сессии
wsClient.saveSessionToken(WebSocketNamespace.REASONING, 'session-token');
// Получение сохраненного токена
const token = wsClient.getSessionToken(WebSocketNamespace.REASONING);
// Очистка токена сессии
wsClient.clearSessionToken(WebSocketNamespace.REASONING);
// Включение/отключение сохранения сессий при создании SDK
const sdk = new CodeSolverSDK({
baseURL: 'https://api.example.com',
apiKey: 'your-api-key',
websocket: {
enableSessionPersistence: true // Включить сохранение токенов сессий
}
});
```
## Проверка здоровья соединений
SDK предоставляет механизм регулярной проверки здоровья соединений и автоматического переподключения при обнаружении проблем:
```javascript
// Настройка проверки здоровья соединений
wsClient.setupConnectionHealthCheck(
30000 // Интервал проверки в миллисекундах
);
// Отключение проверки здоровья
if (wsClient.healthCheckTimer) {
clearInterval(wsClient.healthCheckTimer);
wsClient.healthCheckTimer = null;
}
```
## Работа с ping/pong
Для поддержания активных соединений и измерения времени отклика SDK использует механизм ping/pong:
```javascript
// Включение автоматического ping/pong
wsClient.enablePingPong(
15000, // Интервал между ping-сообщениями (мс)
3 // Порог таймаута (количество пропущенных pong)
);
// Отключение механизма ping/pong
wsClient.disablePingPong();
// Получение статистики ping/pong
const stats = wsClient.getPingStats(WebSocketNamespace.REASONING);
console.log('Статистика ping/pong:', stats);
// Подписка на события таймаута соединения
wsClient.onPingPongEvent('connection_timeout', (data) => {
console.log('Таймаут соединения:', data);
});
```
## Примеры использования
### Работа с потоковой передачей мышления
```javascript
const { CodeSolverSDK } = require('solver-sdk');
async function streamingThinking() {
const sdk = new CodeSolverSDK({
baseURL: 'https://api.example.com',
apiKey: 'ваш-ключ-api',
websocket: {
reconnect: true,
pingInterval: 30000
}
});
// Подключаем WebSocket
await sdk.chat.connectWebSocket();
// Создаем буферы для накопления контента
let thinkingBuffer = '';
let responseBuffer = '';
// Настраиваем обработчик событий
const handleEvent = (eventType, data) => {
switch(eventType) {
case 'thinking_delta':
thinkingBuffer += data.text || '';
// Обновляем UI с мышлением
updateThinkingUI(thinkingBuffer);
break;
case 'text_delta':
responseBuffer += data.text || '';
// Обновляем UI с ответом
updateResponseUI(responseBuffer);
break;
case 'message_stop':
console.log('Обработка завершена');
break;
}
};
// Отправляем запрос
const messages = [
{ role: 'user', content: 'Объясни принцип работы квантового компьютера' }
];
try {
const response = await sdk.chat.streamChatWithThinking(
messages,
{
model: 'claude-3-7-sonnet-20240229',
thinking: true,
temperature: 0.7
},
handleEvent
);
console.log('Запрос отправлен, ID сокета:', response.socketId);
// После завершения можно отключиться
setTimeout(() => {
sdk.chat.disconnectWebSocket();
console.log('Соединение закрыто');
}, 1000);
return {
thinking: thinkingBuffer,
response: responseBuffer
};
} catch (error) {
console.error('Ошибка при отправке запроса:', error);
sdk.chat.disconnectWebSocket();
throw error;
}
}
// Функции для обновления UI
function updateThinkingUI(text) {
console.log('Обновление блока мышления');
// document.getElementById('thinking-container').textContent = text;
}
function updateResponseUI(text) {
console.log('Обновление блока ответа');
// document.getElementById('response-container').textContent = text;
}
// Запуск функции
streamingThinking().catch(console.error);
```
### Работа с региональным переключением
```javascript
const { CodeSolverSDK } = require('solver-sdk');
async function chatWithRegionalFailover() {
const sdk = new CodeSolverSDK({
baseURL: 'https://api.example.com',
apiKey: 'ваш-ключ-api',
providers: {
anthropic: {
region: 'us-east-1' // Базовый регион
}
}
});
// Подключаем WebSocket
await sdk.chat.connectWebSocket();
// Настраиваем обработчик для отображения региона и ошибок
sdk.chat.on('region_switch', (data) => {
console.log(`Переключение на регион: ${data.region}`);
});
sdk.chat.on('error', (data) => {
console.error('Ошибка:', data);
});
// Отправляем запрос с автоматическим переключением регионов при ошибках
try {
const response = await sdk.chat.chatWithRegionFailover(
[{ role: 'user', content: 'Расскажи о квантовой физике' }],
{
model: 'claude-3-7-sonnet-20240229',
thinking: true,
// Порядок перебора регионов при ошибках
regionPreference: ['us-east-1', 'eu-west-1', 'ap-southeast-2']
}
);
console.log('Ответ получен из региона:', response.region);
console.log('Ответ:', response.choices[0].message.content);
return response;
} catch (error) {
console.error('Не удалось получить ответ ни из одного региона:', error);
throw error;
} finally {
await sdk.chat.disconnectWebSocket();
}
}
chatWithRegionalFailover().catch(console.error);
```
## Справочник всех событий WebSocket
Полный список всех поддерживаемых WebSocket событий, их описание, формат данных и примеры использования доступны в отдельном документе:
[Справочник WebSocket событий SDK](./WEBSOCKET_EVENTS.md)
В этом справочнике содержится подробная информация обо всех константах событий, их строковых значениях, форматах данных и рекомендациях по использованию в различных сценариях.