diff --git a/dist/manager-CYx1MWZA.js b/dist/manager-CYx1MWZA.js
index 1234567..abcdefg 100644
--- a/dist/manager-CYx1MWZA.js
+++ b/dist/manager-CYx1MWZA.js
@@ -2595,6 +2595,30 @@ var MemoryManagerEmbeddingOps = class extends MemoryManagerSyncOps {
 	async embedChunksInBatches(chunks) {
 		if (chunks.length === 0) return [];
 		const { embeddings, missing } = this.collectCachedEmbeddings(chunks);
+		// Preemptive throttling untuk Gemini: tracking request count per menit
+		const isGemini = this.provider?.id === "gemini";
+		if (isGemini) {
+			const now = Date.now();
+			if (!MemoryManagerEmbeddingOps._geminiRequestCounter) {
+				MemoryManagerEmbeddingOps._geminiRequestCounter = { count: 0, windowStart: now };
+			}
+			const counter = MemoryManagerEmbeddingOps._geminiRequestCounter;
+			if (now - counter.windowStart >= 60000) {
+				counter.count = 0;
+				counter.windowStart = now;
+			}
+			if (counter.count >= 100) {
+				const waitMs = 60000 - (now - counter.windowStart) + 1000;
+				log$1.warn(`memory embeddings: approaching rate limit (100 req/min), waiting ${Math.round(waitMs / 1000)}s...`);
+				await new Promise((resolve) => setTimeout(resolve, waitMs));
+				counter.count = 0;
+				counter.windowStart = Date.now();
+			}
+			counter.count++;
+		}
 		if (missing.length === 0) return embeddings;
 		const missingChunks = missing.map((m) => m.chunk);
 		const batches = this.buildEmbeddingBatches(missingChunks);
@@ -2836,6 +2860,30 @@ var MemoryManagerEmbeddingOps = class extends MemoryManagerSyncOps {
 	async embedBatchWithRetry(texts) {
 		if (texts.length === 0) return [];
 		if (!this.provider) throw new Error("Cannot embed batch in FTS-only mode (no embedding provider)");
+		// Preemptive throttling: tracking request count per menit untuk Gemini
+		const isGemini = this.provider?.id === "gemini";
+		if (isGemini) {
+			const now = Date.now();
+			// Inisialisasi counter jika belum ada
+			if (!MemoryManagerEmbeddingOps._geminiRequestCounter) {
+				MemoryManagerEmbeddingOps._geminiRequestCounter = { count: 0, windowStart: now };
+			}
+			const counter = MemoryManagerEmbeddingOps._geminiRequestCounter;
+			// Reset counter jika sudah lewat 1 menit
+			if (now - counter.windowStart >= 60000) {
+				counter.count = 0;
+				counter.windowStart = now;
+			}
+			// Kalau sudah 100 request dalam 1 menit, tunggu sampai window reset
+			if (counter.count >= 100) {
+				const waitMs = 60000 - (now - counter.windowStart) + 1000; // +1s buffer
+				log$1.warn(`memory embeddings: approaching rate limit (100 req/min), waiting ${Math.round(waitMs / 1000)}s before continuing...`);
+				await new Promise((resolve) => setTimeout(resolve, waitMs));
+				// Reset counter setelah tunggu
+				counter.count = 0;
+				counter.windowStart = Date.now();
+			}
+			counter.count++;
+		}
 		let attempt = 0;
 		let delayMs = EMBEDDING_RETRY_BASE_DELAY_MS;
 		while (true) try {
@@ -2847,10 +2895,12 @@ var MemoryManagerEmbeddingOps = class extends MemoryManagerSyncOps {
 			return await this.withTimeout(this.provider.embedBatch(texts), timeoutMs, `memory embeddings batch timed out after ${Math.round(timeoutMs / 1e3)}s`);
 		} catch (err) {
 			const message = err instanceof Error ? err.message : String(err);
-			if (!this.isRetryableEmbeddingError(message) || attempt >= EMBEDDING_RETRY_MAX_ATTEMPTS) throw err;
-			const waitMs = Math.min(EMBEDDING_RETRY_MAX_DELAY_MS, Math.round(delayMs * (1 + Math.random() * .2)));
-			log$1.warn(`memory embeddings rate limited; retrying in ${waitMs}ms`);
+			// Cek apakah rate limit 429 dengan retry after
+			const isRateLimit = /rate[_ ]limit|too many requests|429|resource has been exhausted/i.test(message);
+			if (!isRateLimit || attempt >= EMBEDDING_RETRY_MAX_ATTEMPTS) throw err;
+			// Jika rate limit 429, tunggu 1 menit (60000ms) sebelum retry
+			const isQuotaExceeded = /exceeded.*quota|limit.*100|embed_content_free_tier/i.test(message);
+			const waitMs = isQuotaExceeded ? 60000 : Math.min(EMBEDDING_RETRY_MAX_DELAY_MS, Math.round(delayMs * (1 + Math.random() * .2)));
+			log$1.warn(`memory embeddings rate limited${isQuotaExceeded ? " (quota exceeded, waiting 1 min)" : ""}; retrying in ${waitMs}ms`);
 			await new Promise((resolve) => setTimeout(resolve, waitMs));
-			delayMs *= 2;
+			if (!isQuotaExceeded) delayMs *= 2;
 			attempt += 1;
 		}
 	}
@@ -2871,10 +2921,12 @@ var MemoryManagerEmbeddingOps = class extends MemoryManagerSyncOps {
 			return await this.withTimeout(this.provider.embedQuery(text), timeoutMs, `memory embeddings query timed out after ${Math.round(timeoutMs / 1e3)}s`);
 		} catch (err) {
 			const message = err instanceof Error ? err.message : String(err);
-			if (!this.isRetryableEmbeddingError(message) || attempt >= EMBEDDING_RETRY_MAX_ATTEMPTS) throw err;
-			const waitMs = Math.min(EMBEDDING_RETRY_MAX_DELAY_MS, Math.round(delayMs * (1 + Math.random() * .2)));
-			log$1.warn(`memory embeddings rate limited; retrying in ${waitMs}ms`);
+			// Cek apakah rate limit 429 dengan retry after
+			const isRateLimit = /rate[_ ]limit|too many requests|429|resource has been exhausted/i.test(message);
+			if (!isRateLimit || attempt >= EMBEDDING_RETRY_MAX_ATTEMPTS) throw err;
+			// Jika rate limit 429, tunggu 1 menit (60000ms) sebelum retry
+			const isQuotaExceeded = /exceeded.*quota|limit.*100|embed_content_free_tier/i.test(message);
+			const waitMs = isQuotaExceeded ? 60000 : Math.min(EMBEDDING_RETRY_MAX_DELAY_MS, Math.round(delayMs * (1 + Math.random() * .2)));
+			log$1.warn(`memory embeddings rate limited${isQuotaExceeded ? " (quota exceeded, waiting 1 min)" : ""}; retrying in ${waitMs}ms`);
 			await new Promise((resolve) => setTimeout(resolve, waitMs));
-			delayMs *= 2;
+			if (!isQuotaExceeded) delayMs *= 2;
 			attempt += 1;
 		}
 	}
