From a7d12c264b4610ac53cb9c714f173c5ae000c5c9 Mon Sep 17 00:00:00 2001 From: Kevin Taylor Date: Mon, 18 Aug 2025 10:37:14 -0700 Subject: [PATCH] Add Cerebras rate limit handler --- packages/opencode/src/provider/provider.ts | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 42bb1804..9221b89c 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -133,6 +133,38 @@ export namespace Provider { }, } }, + cerebras: async () => { + return { + autoload: false, + async getModel(sdk: any, modelID: string) { + const originalModel = sdk.languageModel(modelID) + + // Cerebras hits rate limits quickly, so wrap calls with retry logic + const retryCall = async (fn: () => Promise) => { + for (let attempt = 0; attempt <= 6; attempt++) { + try { + return await fn() + } catch (error: any) { + // Don't retry on final attempt or non-retryable errors (auth/client errors) + if (attempt === 6 || (error?.status !== 429 && error?.status < 500)) { + throw error + } + // Exponential backoff capped at 60s (since hourly/daily limits are the same) + const delay = Math.min(5000 * Math.pow(2, attempt), 60000) + await new Promise(resolve => setTimeout(resolve, delay)) + } + } + } + + // Wrap both generation methods with silent retry logic + return { + ...originalModel, + doGenerate: async (...args: any[]) => retryCall(() => originalModel.doGenerate(...args)), + doStream: async (...args: any[]) => retryCall(() => originalModel.doStream(...args)) + } + }, + } + }, } const state = App.state("provider", async () => {