From 70fa2e257881fe60b79c5a567973626ca22f8459 Mon Sep 17 00:00:00 2001 From: SatoshiReport Date: Mon, 14 Jul 2025 22:52:41 -0400 Subject: [PATCH] feat: add embedding rate limiting to prevent API quota exhaustion - Add EMBEDDING_CALL_DELAY_MS constant (100ms) to prevent rate limiting - Implement delays after embedding calls in file-watcher.ts - Implement delays after embedding calls in scanner.ts - Helps prevent HTTP 429 errors during code indexing operations --- src/services/code-index/constants/index.ts | 3 +++ src/services/code-index/processors/file-watcher.ts | 4 ++++ src/services/code-index/processors/scanner.ts | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/src/services/code-index/constants/index.ts b/src/services/code-index/constants/index.ts index c2567f5635b..1ab2f26a551 100644 --- a/src/services/code-index/constants/index.ts +++ b/src/services/code-index/constants/index.ts @@ -28,3 +28,6 @@ export const BATCH_PROCESSING_CONCURRENCY = 10 /**Gemini Embedder */ export const GEMINI_MAX_ITEM_TOKENS = 2048 + +/**Embedding Rate Limiting */ +export const EMBEDDING_CALL_DELAY_MS = 100 // Pause between embedding API calls to prevent rate limiting diff --git a/src/services/code-index/processors/file-watcher.ts b/src/services/code-index/processors/file-watcher.ts index 6dc1cd1835d..81e2dce1b8e 100644 --- a/src/services/code-index/processors/file-watcher.ts +++ b/src/services/code-index/processors/file-watcher.ts @@ -5,6 +5,7 @@ import { BATCH_SEGMENT_THRESHOLD, MAX_BATCH_RETRIES, INITIAL_RETRY_DELAY_MS, + EMBEDDING_CALL_DELAY_MS, } from "../constants" import { createHash } from "crypto" import { RooIgnoreController } from "../../../core/ignore/RooIgnoreController" @@ -542,6 +543,9 @@ export class FileWatcher implements IFileWatcher { if (this.embedder && blocks.length > 0) { const texts = blocks.map((block) => block.content) const { embeddings } = await this.embedder.createEmbeddings(texts) + + // Add pause between embedding calls to prevent rate limiting + await new Promise(resolve => setTimeout(resolve, EMBEDDING_CALL_DELAY_MS)) pointsToUpsert = blocks.map((block, index) => { const normalizedAbsolutePath = generateNormalizedAbsolutePath(block.file_path, this.workspacePath) diff --git a/src/services/code-index/processors/scanner.ts b/src/services/code-index/processors/scanner.ts index 538a1252d78..bd9cbe01631 100644 --- a/src/services/code-index/processors/scanner.ts +++ b/src/services/code-index/processors/scanner.ts @@ -23,6 +23,7 @@ import { INITIAL_RETRY_DELAY_MS, PARSING_CONCURRENCY, BATCH_PROCESSING_CONCURRENCY, + EMBEDDING_CALL_DELAY_MS, } from "../constants" import { isPathInIgnoredDirectory } from "../../glob/ignore-utils" import { TelemetryService } from "@roo-code/telemetry" @@ -344,6 +345,9 @@ export class DirectoryScanner implements IDirectoryScanner { // Create embeddings for batch const { embeddings } = await this.embedder.createEmbeddings(batchTexts) + + // Add pause between embedding calls to prevent rate limiting + await new Promise(resolve => setTimeout(resolve, EMBEDDING_CALL_DELAY_MS)) // Prepare points for Qdrant const points = batchBlocks.map((block, index) => {