diff --git a/open-sse/config/errorConfig.js b/open-sse/config/errorConfig.js index 4c13b5db..520b3d59 100644 --- a/open-sse/config/errorConfig.js +++ b/open-sse/config/errorConfig.js @@ -31,7 +31,7 @@ export const DEFAULT_ERROR_MESSAGES = { // Exponential backoff config for rate limits export const BACKOFF_CONFIG = { base: 1000, - max: 3 * 60 * 1000, + max: 4 * 60 * 1000, maxLevel: 15 }; diff --git a/open-sse/services/accountFallback.js b/open-sse/services/accountFallback.js index 766d69e7..8d280da4 100644 --- a/open-sse/services/accountFallback.js +++ b/open-sse/services/accountFallback.js @@ -2,12 +2,13 @@ import { ERROR_RULES, BACKOFF_CONFIG, TRANSIENT_COOLDOWN_MS } from "../config/er /** * Calculate exponential backoff cooldown for rate limits (429) - * Level 0: 1s, Level 1: 2s, Level 2: 4s... → max 2 min + * Level 1: 1s, Level 2: 2s, Level 3: 4s... → max 4 min * @param {number} backoffLevel - Current backoff level * @returns {number} Cooldown in milliseconds */ export function getQuotaCooldown(backoffLevel = 0) { - const cooldown = BACKOFF_CONFIG.base * Math.pow(2, backoffLevel); + const level = Math.max(0, backoffLevel - 1); + const cooldown = BACKOFF_CONFIG.base * Math.pow(2, level); return Math.min(cooldown, BACKOFF_CONFIG.max); } @@ -29,7 +30,7 @@ export function checkFallbackError(status, errorText, backoffLevel = 0) { if (rule.text && lowerError && lowerError.includes(rule.text)) { if (rule.backoff) { const newLevel = Math.min(backoffLevel + 1, BACKOFF_CONFIG.maxLevel); - return { shouldFallback: true, cooldownMs: getQuotaCooldown(backoffLevel), newBackoffLevel: newLevel }; + return { shouldFallback: true, cooldownMs: getQuotaCooldown(newLevel), newBackoffLevel: newLevel }; } return { shouldFallback: true, cooldownMs: rule.cooldownMs }; } @@ -38,7 +39,7 @@ export function checkFallbackError(status, errorText, backoffLevel = 0) { if (rule.status && rule.status === status) { if (rule.backoff) { const newLevel = Math.min(backoffLevel + 1, BACKOFF_CONFIG.maxLevel); - return { shouldFallback: true, cooldownMs: getQuotaCooldown(backoffLevel), newBackoffLevel: newLevel }; + return { shouldFallback: true, cooldownMs: getQuotaCooldown(newLevel), newBackoffLevel: newLevel }; } return { shouldFallback: true, cooldownMs: rule.cooldownMs }; } diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/ClaudeToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/ClaudeToolCard.js index fa65b4d6..a94e2080 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/ClaudeToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/ClaudeToolCard.js @@ -253,14 +253,16 @@ export default function ClaudeToolCard({ {!checkingClaude && claudeStatus && !claudeStatus.installed && (
-
- warning -
-

Claude CLI not detected locally

-

Manual configuration is still available if 9router is deployed on a remote server.

+
+
+ warning +
+

Claude CLI not detected locally

+

Manual configuration is still available if 9router is deployed on a remote server.

+
-
- diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/CodexToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/CodexToolCard.js index efb5c27a..8a710c94 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/CodexToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/CodexToolCard.js @@ -220,16 +220,24 @@ model = "${effectiveSubagentModel}" {!checkingCodex && codexStatus && !codexStatus.installed && (
-
- warning -
-

Codex CLI not installed

-

Please install Codex CLI to use auto-apply feature.

+
+
+ warning +
+

Codex CLI not detected locally

+

Manual configuration is still available if 9router is deployed on a remote server.

+
+
+
+ +
-
{showInstallGuide && (
diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/DroidToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/DroidToolCard.js index b8edebc5..9cd890ac 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/DroidToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/DroidToolCard.js @@ -28,6 +28,7 @@ export default function DroidToolCard({ const [modalOpen, setModalOpen] = useState(false); const [modelAliases, setModelAliases] = useState({}); const [showManualConfigModal, setShowManualConfigModal] = useState(false); + const [showInstallGuide, setShowInstallGuide] = useState(false); const [customBaseUrl, setCustomBaseUrl] = useState(""); const hasInitializedModel = useRef(false); @@ -246,12 +247,38 @@ export default function DroidToolCard({ )} {!checkingDroid && droidStatus && !droidStatus.installed && ( -
- warning -
-

Factory Droid CLI not installed

-

Please install Factory Droid CLI to use this feature.

+
+
+
+ warning +
+

Factory Droid CLI not detected locally

+

Manual configuration is still available if 9router is deployed on a remote server.

+
+
+
+ + +
+ {showInstallGuide && ( +
+

Installation Guide

+
+
+

macOS / Linux / Windows:

+ curl -fsSL https://app.factory.ai/cli | sh +
+

After installation, run droid to verify.

+
+
+ )}
)} diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/OpenClawToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/OpenClawToolCard.js index 4fac7eb8..35daf3c4 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/OpenClawToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/OpenClawToolCard.js @@ -254,19 +254,21 @@ export default function OpenClawToolCard({ )} {!checkingOpenclaw && openclawStatus && !openclawStatus.installed && ( -
-
- warning -
-

Open Claw CLI not installed

-

Please install Open Claw CLI to use this feature.

+
+
+
+ warning +
+

Open Claw CLI not detected locally

+

Manual configuration is still available if 9router is deployed on a remote server.

+
+
+
+
-
- {/* Show manual config option even when detection fails */} -
-
)} diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/OpenCodeToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/OpenCodeToolCard.js index 3fd55e94..4a5a2662 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/OpenCodeToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/OpenCodeToolCard.js @@ -218,16 +218,24 @@ export default function OpenCodeToolCard({ tool, isExpanded, onToggle, baseUrl, {!checking && status && !status.installed && (
-
- warning -
-

OpenCode CLI not installed

-

Please install OpenCode CLI to use auto-apply feature.

+
+
+ warning +
+

OpenCode CLI not detected locally

+

Manual configuration is still available if 9router is deployed on a remote server.

+
+
+
+ +
-
{showInstallGuide && (