|
| 1 | +# Полное резюме чата: Embedding Indexing Fix |
| 2 | + |
| 3 | +## Дата: 2026-04-04 |
| 4 | + |
| 5 | +## Ветка: `fix/embedding-indexing-timeouts-and-retry` |
| 6 | + |
| 7 | +## PR: https://github.com/RooCodeInc/Roo-Code/pull/12059 |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +## 1. ИСХОДНАЯ ПРОБЛЕМА |
| 12 | + |
| 13 | +При индексации кодовой базы через OpenAI-совместимый API (Ollama на `http://0.0.0.0:11434/v1`) возникала ошибка: |
| 14 | + |
| 15 | +``` |
| 16 | +Indexing partially failed: Only 780 of 2834 blocks were indexed. |
| 17 | +Не удалось создать вложения после 3 попыток: HTTP 503 - 503 status code (no body) |
| 18 | +``` |
| 19 | + |
| 20 | +**Корневая причина:** OpenAI Compatible Embedder не имел таймаутов и не ретраил 5xx ошибки. Сервер мог зависать — программа ждала бесконечно. |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## 2. ПЛАН РЕАЛИЗАЦИИ |
| 25 | + |
| 26 | +Создан детальный план в файле `embedding-indexing-fix.md` с 9 шагами: |
| 27 | + |
| 28 | +- Шаги 1-4: Таймауты, AbortController, retry 5xx (критические) |
| 29 | +- Шаги 5-6: i18n ключи (средний приоритет) |
| 30 | +- Шаги 7-9: Тесты |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## 3. РЕАЛИЗОВАННЫЕ ИЗМЕНЕНИЯ |
| 35 | + |
| 36 | +### 3.1. `src/services/code-index/embedders/openai-compatible.ts` |
| 37 | + |
| 38 | +**Шаг 1 — Константы таймаутов (строки 17-19):** |
| 39 | + |
| 40 | +```typescript |
| 41 | +const OPENAI_COMPATIBLE_EMBEDDING_TIMEOUT_MS = 60000 // 60 секунд |
| 42 | +const OPENAI_COMPATIBLE_VALIDATION_TIMEOUT_MS = 30000 // 30 секунд |
| 43 | +``` |
| 44 | + |
| 45 | +**Шаг 2 — OpenAI SDK constructor (строки 77-82):** |
| 46 | + |
| 47 | +```typescript |
| 48 | +this.embeddingsClient = new OpenAI({ |
| 49 | + baseURL: baseUrl, |
| 50 | + apiKey: apiKey, |
| 51 | + timeout: OPENAI_COMPATIBLE_EMBEDDING_TIMEOUT_MS, // 60 секунд таймаут |
| 52 | + maxRetries: 0, // Отключаем встроенный retry SDK |
| 53 | +}) |
| 54 | +``` |
| 55 | + |
| 56 | +**Шаг 3 — AbortController в makeDirectEmbeddingRequest() (строки 208-274):** |
| 57 | + |
| 58 | +- Добавлен `AbortController` с таймаутом 60с |
| 59 | +- `signal: controller.signal` в fetch options |
| 60 | +- `clearTimeout(timeoutId)` после ответа И в catch |
| 61 | +- Обработка `AbortError` → преобразование в HTTP 504 (Gateway Timeout) |
| 62 | + |
| 63 | +**Шаг 4 — Retry для 5xx (строки 350-377):** |
| 64 | + |
| 65 | +```typescript |
| 66 | +const errorStatus = httpError?.status |
| 67 | +const isRetryableServerError = typeof errorStatus === "number" && errorStatus >= 500 && errorStatus < 600 |
| 68 | +const isRateLimitError = errorStatus === 429 |
| 69 | + |
| 70 | +if (isRateLimitError) { |
| 71 | + await this.updateGlobalRateLimitState(httpError) |
| 72 | +} |
| 73 | + |
| 74 | +if ((isRateLimitError || isRetryableServerError) && hasMoreAttempts) { |
| 75 | + // retry с exponential backoff |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +**Исправление TypeScript ошибки (строка 353):** |
| 80 | +Заменено `httpError?.status >= 500` на `typeof errorStatus === "number" && errorStatus >= 500` для устранения TS18048. |
| 81 | + |
| 82 | +### 3.2. `src/services/code-index/shared/validation-helpers.ts` |
| 83 | + |
| 84 | +**Обновлен getErrorMessageForStatus() (строки 69-92):** |
| 85 | + |
| 86 | +- 429 → `rateLimitExceeded` (вместо `serviceUnavailable`) |
| 87 | +- 502 → `badGateway` (новый) |
| 88 | +- 503 → `serviceUnavailable` |
| 89 | +- 504 → `gatewayTimeout` (новый) |
| 90 | +- Остальные 5xx → `serverError` (вместо `configurationError`) |
| 91 | + |
| 92 | +### 3.3. i18n переводы (18 файлов) |
| 93 | + |
| 94 | +Обновлены 18 locale файлов (`en, ru, de, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, tr, vi, zh-CN, zh-TW, ca`): |
| 95 | + |
| 96 | +**Новые ключи в корне:** |
| 97 | + |
| 98 | +- `serverErrorRetry`: "Server error ({{status}}), retrying in {{delayMs}}ms (attempt {{attempt}}/{{maxRetries}})" |
| 99 | + |
| 100 | +**Новые ключи в validation:** |
| 101 | + |
| 102 | +- `rateLimitExceeded`: "Rate limit exceeded. Please try again later." |
| 103 | +- `badGateway`: "Bad gateway error from embedder service. The server received an invalid response." |
| 104 | +- `serviceUnavailable`: "Embedding service temporarily unavailable. Please try again later." |
| 105 | +- `gatewayTimeout`: "Gateway timeout error. The embedder service did not respond in time." |
| 106 | +- `serverError`: "Server error from embedder service. Please try again later." |
| 107 | + |
| 108 | +### 3.4. Тесты |
| 109 | + |
| 110 | +**`openai-compatible.spec.ts`:** |
| 111 | + |
| 112 | +- Обновлен тест "should throw error immediately on non-retryable errors" → "should retry on 5xx server errors" (теперь 3 попытки вместо 1) |
| 113 | +- Добавлены тесты `timeout handling` (2 теста) |
| 114 | +- Добавлены тесты `5xx retry handling` (3 теста: 502, 503, 504) |
| 115 | +- Обновлены тесты validateConfiguration для новых статусов |
| 116 | + |
| 117 | +**`openai.spec.ts`:** |
| 118 | + |
| 119 | +- Исправлен тест validateConfiguration для 500 → `serverError` |
| 120 | +- Исправлен тест validateConfiguration для 429 → `rateLimitExceeded` |
| 121 | + |
| 122 | +**`validation-helpers.spec.ts`:** |
| 123 | + |
| 124 | +- Добавлены 10 тестов для `getErrorMessageForStatus` (401, 403, 404, 429, 502, 503, 504, 5xx, undefined) |
| 125 | + |
| 126 | +--- |
| 127 | + |
| 128 | +## 4. РЕЗУЛЬТАТЫ ТЕСТОВ |
| 129 | + |
| 130 | +### Локальные тесты: |
| 131 | + |
| 132 | +- **code-index tests:** 482 passed, 0 failed |
| 133 | +- **Все тесты проекта:** 8210 total (8154 passed, 57 skipped, 0 failed) |
| 134 | +- **Test files:** 582 (569 run, 13 skipped) |
| 135 | +- **Duration:** 4m44s |
| 136 | + |
| 137 | +### CI проверки в PR: |
| 138 | + |
| 139 | +- ✅ **knip:** passed |
| 140 | +- ✅ **compile (TypeScript + ESLint):** passed |
| 141 | +- ✅ **platform-unit-test (ubuntu-latest):** passed |
| 142 | +- ❌ **check-translations:** failed (исправлено — добавлены каталонские переводы) |
| 143 | +- ⏳ **platform-unit-test (windows-latest):** in progress |
| 144 | + |
| 145 | +--- |
| 146 | + |
| 147 | +## 5. ИСПРАВЛЕНИЕ КАТАЛОНСКИХ ПЕРЕВОДОВ |
| 148 | + |
| 149 | +CI `check-translations` упал из-за отсутствия 5 ключей в `ca/embeddings.json`: |
| 150 | + |
| 151 | +- `serverErrorRetry` |
| 152 | +- `validation.rateLimitExceeded` |
| 153 | +- `validation.badGateway` |
| 154 | +- `validation.gatewayTimeout` |
| 155 | +- `validation.serverError` |
| 156 | + |
| 157 | +Добавлены каталонские переводы, запушен коммит `db7690428`. |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +## 6. GIT СТРУКТУРА |
| 162 | + |
| 163 | +**Remote репозитории:** |
| 164 | + |
| 165 | +- `origin` → `https://github.com/DScoNOIZ/Roo-Code.git` (форк пользователя) |
| 166 | +- `upstream` → `https://github.com/RooCodeInc/Roo-Code.git` (оригинал) |
| 167 | +- `dsconoi` → тот же форк с токеном |
| 168 | + |
| 169 | +**Коммиты в ветке:** |
| 170 | + |
| 171 | +1. `c5eb84b76` — основные изменения (23 файла) |
| 172 | +2. `db7690428` — исправление каталонских переводов (1 файл) |
| 173 | + |
| 174 | +**Rebase на upstream/main:** ✅ Без конфликтов |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## 7. PULL REQUEST |
| 179 | + |
| 180 | +**Ссылка:** https://github.com/RooCodeInc/Roo-Code/pull/12059 |
| 181 | + |
| 182 | +**Описание PR включает:** |
| 183 | + |
| 184 | +- Историю успеха Roo Code (всё сделано с помощью Roo Code, человек только давал команды) |
| 185 | +- Благодарность команде Roo Code |
| 186 | +- Техническое описание проблемы и решения |
| 187 | +- Таблицу изменений |
| 188 | +- Результаты проверок |
| 189 | +- Ссылку на IMPLEMENTATION-REPORT.md в форке пользователя |
| 190 | + |
| 191 | +--- |
| 192 | + |
| 193 | +## 8. VSIX СБОРКА |
| 194 | + |
| 195 | +Собран VSIX пакет успешно: |
| 196 | + |
| 197 | +- **Имя файла:** `roo-cline-3.51.1.vsix` |
| 198 | +- **Размер:** 32 МБ |
| 199 | +- **Файлов:** 1758 |
| 200 | +- **Время сборки:** 15.133s |
| 201 | +- **Команда:** `pnpm vsix` |
| 202 | + |
| 203 | +--- |
| 204 | + |
| 205 | +## 9. КЛЮЧЕВЫЕ ФАЙЛЫ |
| 206 | + |
| 207 | +| Файл | Изменения | |
| 208 | +| ----------------------------------------------------------------------- | ------------------------------------ | |
| 209 | +| `src/services/code-index/embedders/openai-compatible.ts` | Таймауты, AbortController, 5xx retry | |
| 210 | +| `src/services/code-index/shared/validation-helpers.ts` | Новые сообщения об ошибках | |
| 211 | +| `src/i18n/locales/*/embeddings.json` (18 файлов) | Новые i18n ключи | |
| 212 | +| `src/services/code-index/embedders/__tests__/openai-compatible.spec.ts` | 5 новых тестов | |
| 213 | +| `src/services/code-index/embedders/__tests__/openai.spec.ts` | Исправление регрессии | |
| 214 | +| `src/services/code-index/shared/__tests__/validation-helpers.spec.ts` | 10 новых тестов | |
| 215 | + |
| 216 | +--- |
| 217 | + |
| 218 | +## 10. ЧТО ОСТАЛОСЬ |
| 219 | + |
| 220 | +- Дождаться прохождения всех CI проверок в PR |
| 221 | +- Дождаться ревью от мейнтейнеров RooCodeInc |
| 222 | +- Возможны запросы на изменения после ревью |
0 commit comments