mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-27 09:02:15 +00:00
fix: escalate to model fallback after rate-limit profile rotation cap (#58707)
* fix: escalate to model fallback after rate-limit profile rotation cap Per-model rate limits (e.g. Anthropic Sonnet-only quotas) are not relieved by rotating auth profiles — if all profiles share the same model quota, cycling between them loops forever without falling back to the next model in the configured fallbacks chain. Apply the same rotation-cap pattern introduced for overloaded_error (#58348) to rate_limit errors: - Add `rateLimitedProfileRotations` to auth.cooldowns config (default: 1) - After N profile rotations on a rate_limit error, throw FailoverError to trigger cross-provider model fallback - Add `resolveRateLimitProfileRotationLimit` helper following the same pattern as `resolveOverloadProfileRotationLimit` Fixes #58572 * fix: cap prompt-side rate-limit failover (#58707) (thanks @Forgely3D) * fix: restore latest-main gates for #58707 --------- Co-authored-by: Ember (Forgely3D) <ember@forgely.co> Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -22,7 +22,10 @@ import {
|
||||
resolveUsageProviderId,
|
||||
} from "../../infra/provider-usage.js";
|
||||
import type { MediaUnderstandingDecision } from "../../media-understanding/types.js";
|
||||
import { listTasksForAgentId, listTasksForSessionKey } from "../../tasks/task-registry.js";
|
||||
import {
|
||||
listTasksForAgentIdForStatus,
|
||||
listTasksForSessionKeyForStatus,
|
||||
} from "../../tasks/task-status-access.js";
|
||||
import {
|
||||
buildTaskStatusSnapshot,
|
||||
formatTaskStatusDetail,
|
||||
@@ -61,7 +64,7 @@ function shouldLoadUsageSummary(params: {
|
||||
}
|
||||
|
||||
function formatSessionTaskLine(sessionKey: string): string | undefined {
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForSessionKey(sessionKey));
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForSessionKeyForStatus(sessionKey));
|
||||
const task = snapshot.focus;
|
||||
if (!task) {
|
||||
return undefined;
|
||||
@@ -79,7 +82,7 @@ function formatSessionTaskLine(sessionKey: string): string | undefined {
|
||||
}
|
||||
|
||||
function formatAgentTaskCountsLine(agentId: string): string | undefined {
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForAgentId(agentId));
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForAgentIdForStatus(agentId));
|
||||
if (snapshot.totalCount === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ import { resolveSessionAgentId } from "../../agents/agent-scope.js";
|
||||
import { logVerbose } from "../../globals.js";
|
||||
import { formatDurationCompact } from "../../infra/format-time/format-duration.ts";
|
||||
import { formatTimeAgo } from "../../infra/format-time/format-relative.ts";
|
||||
import { listTasksForAgentId, listTasksForSessionKey } from "../../tasks/task-registry.js";
|
||||
import type { TaskRecord } from "../../tasks/task-registry.types.js";
|
||||
import {
|
||||
listTasksForAgentIdForStatus,
|
||||
listTasksForSessionKeyForStatus,
|
||||
} from "../../tasks/task-status-access.js";
|
||||
import { buildTaskStatusSnapshot } from "../../tasks/task-status.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
import type { CommandHandler, HandleCommandsParams } from "./commands-types.js";
|
||||
@@ -35,7 +38,7 @@ function formatTaskHeadline(snapshot: ReturnType<typeof buildTaskStatusSnapshot>
|
||||
}
|
||||
|
||||
function formatAgentFallbackLine(agentId: string): string | undefined {
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForAgentId(agentId));
|
||||
const snapshot = buildTaskStatusSnapshot(listTasksForAgentIdForStatus(agentId));
|
||||
if (snapshot.totalCount === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -75,7 +78,9 @@ function formatVisibleTask(task: TaskRecord, index: number): string {
|
||||
}
|
||||
|
||||
export function buildTasksText(params: { sessionKey: string; agentId: string }): string {
|
||||
const sessionSnapshot = buildTaskStatusSnapshot(listTasksForSessionKey(params.sessionKey));
|
||||
const sessionSnapshot = buildTaskStatusSnapshot(
|
||||
listTasksForSessionKeyForStatus(params.sessionKey),
|
||||
);
|
||||
const lines = ["📋 Tasks", formatTaskHeadline(sessionSnapshot)];
|
||||
|
||||
if (sessionSnapshot.totalCount > 0) {
|
||||
|
||||
Reference in New Issue
Block a user