惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 司徒正美
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
WordPress大学
WordPress大学
罗磊的独立博客
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Help Net Security
S
SegmentFault 最新的问题
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
Engineering at Meta
Engineering at Meta
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
D
DataBreaches.Net
雷峰网
雷峰网
GbyAI
GbyAI
宝玉的分享
宝玉的分享

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(cron): isolate transient auth cooldowns · openclaw/op...
openperf · 2026-06-14 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -137,7 +137,7 @@ import {

137137

type PostCompactionGuardObservation,

138138

} from "./post-compaction-loop-guard.js";

139139

import { createEmbeddedRunReplayState, observeReplayMetadata } from "./replay-state.js";

140-

import { handleAssistantFailover } from "./run/assistant-failover.js";

140+

import { handleAssistantFailover, isShortWindowRateLimitMessage } from "./run/assistant-failover.js";

141141

import {

142142

createEmbeddedRunStageTracker,

143143

EMBEDDED_RUN_ATTEMPT_DISPATCH_STAGE,

@@ -1418,11 +1418,12 @@ async function runEmbeddedAgentInternal(

14181418

};

14191419

const resolveRunAuthProfileFailureReason = (

14201420

failoverReason: FailoverReason | null,

1421-

opts?: { providerStarted?: boolean },

1421+

opts?: { providerStarted?: boolean; transientRateLimit?: boolean },

14221422

) =>

14231423

resolveAuthProfileFailureReason({

14241424

failoverReason,

14251425

providerStarted: opts?.providerStarted,

1426+

transientRateLimit: opts?.transientRateLimit,

14261427

policy: params.authProfileFailurePolicy,

14271428

});

14281429

const maybeBackoffBeforeOverloadFailover = async (reason: FailoverReason | null) => {

@@ -2695,6 +2696,9 @@ async function runEmbeddedAgentInternal(

26952696

promptFailoverReason,

26962697

{

26972698

providerStarted: promptErrorSource === "prompt",

2699+

transientRateLimit:

2700+

promptFailoverReason === "rate_limit" &&

2701+

isShortWindowRateLimitMessage(errorText),

26982702

},

26992703

);

27002704

const promptFailoverFailure =

@@ -2865,6 +2869,9 @@ async function runEmbeddedAgentInternal(

28652869

assistantProfileFailoverReason,

28662870

{

28672871

providerStarted: assistantProviderStarted,

2872+

transientRateLimit:

2873+

assistantProfileFailoverReason === "rate_limit" &&

2874+

isShortWindowRateLimitMessage(assistantForFailover?.errorMessage),

28682875

},

28692876

);

28702877

const cloudCodeAssistFormatError = attempt.cloudCodeAssistFormatError;

Original file line numberDiff line numberDiff line change

@@ -110,6 +110,10 @@ function resolveShortWindowRateLimitRetry(

110110

return retryAfterSeconds !== null ? { retryAfterSeconds } : {};

111111

}

112112
113+

export function isShortWindowRateLimitMessage(message: string | undefined): boolean {

114+

return resolveShortWindowRateLimitRetry(message) !== null;

115+

}

116+
113117

/**

114118

* Applies an assistant-stage failover decision and returns the next run action.

115119

* It owns auth-profile rotation, overload/rate-limit escalation, same-model

Original file line numberDiff line numberDiff line change

@@ -33,6 +33,40 @@ describe("resolveAuthProfileFailureReason", () => {

3333

).toBeNull();

3434

});

3535
36+

it("keeps only transient local failures out of shared auth state", () => {

37+

expect(

38+

resolveAuthProfileFailureReason({

39+

failoverReason: "rate_limit",

40+

policy: "local_transient",

41+

}),

42+

).toBe("rate_limit");

43+

expect(

44+

resolveAuthProfileFailureReason({

45+

failoverReason: "rate_limit",

46+

policy: "local_transient",

47+

transientRateLimit: true,

48+

}),

49+

).toBeNull();

50+

expect(

51+

resolveAuthProfileFailureReason({

52+

failoverReason: "overloaded",

53+

policy: "local_transient",

54+

}),

55+

).toBeNull();

56+

expect(

57+

resolveAuthProfileFailureReason({

58+

failoverReason: "auth",

59+

policy: "local_transient",

60+

}),

61+

).toBe("auth");

62+

expect(

63+

resolveAuthProfileFailureReason({

64+

failoverReason: "billing",

65+

policy: "local_transient",

66+

}),

67+

).toBe("billing");

68+

});

69+
3670

it("only persists timeouts when the provider request started", () => {

3771

// Pre-provider timeout says nothing about credential health; started

3872

// provider timeouts can cool down the active profile.

Original file line numberDiff line numberDiff line change

@@ -14,6 +14,7 @@ import type { AuthProfileFailurePolicy } from "./auth-profile-failure-policy.typ

1414

export function resolveAuthProfileFailureReason(params: {

1515

failoverReason: FailoverReason | null;

1616

providerStarted?: boolean;

17+

transientRateLimit?: boolean;

1718

policy?: AuthProfileFailurePolicy;

1819

}): AuthProfileFailureReason | null {

1920

// Helper-local runs, transport/server failures, empty responses, and request-shape ("format") rejections

@@ -28,6 +29,9 @@ export function resolveAuthProfileFailureReason(params: {

2829

if (

2930

params.policy === "local" ||

3031

!params.failoverReason ||

32+

(params.policy === "local_transient" &&

33+

(params.failoverReason === "overloaded" ||

34+

(params.failoverReason === "rate_limit" && params.transientRateLimit === true))) ||

3135

params.failoverReason === "server_error" ||

3236

params.failoverReason === "empty_response" ||

3337

params.failoverReason === "format"

Original file line numberDiff line numberDiff line change

@@ -1,4 +1,4 @@

11

/**

22

* Scope used when classifying auth-profile failures for retry/fallback decisions.

33

*/

4-

export type AuthProfileFailurePolicy = "shared" | "local";

4+

export type AuthProfileFailurePolicy = "shared" | "local" | "local_transient";

Original file line numberDiff line numberDiff line change

@@ -1,5 +1,6 @@

11

// Auth profile propagation tests cover isolated agent auth profile forwarding.

22

import { describe, expect, it } from "vitest";

3+

import type { AuthProfileFailurePolicy } from "../agents/embedded-agent-runner/run/auth-profile-failure-policy.types.js";

34

import {

45

makeIsolatedAgentTurnJob,

56

makeIsolatedAgentTurnParams,

@@ -15,17 +16,42 @@ import {

1516
1617

const runCronIsolatedAgentTurn = await loadRunCronIsolatedAgentTurn();

1718
18-

function getEmbeddedAgentParams(): { authProfileId?: string; authProfileIdSource?: string } {

19+

function getEmbeddedAgentParams(): {

20+

authProfileId?: string;

21+

authProfileIdSource?: string;

22+

authProfileFailurePolicy?: AuthProfileFailurePolicy;

23+

} {

1924

const params = runEmbeddedAgentMock.mock.calls[0]?.[0];

2025

if (!params || typeof params !== "object" || Array.isArray(params)) {

2126

throw new Error("Expected embedded OpenClaw agent params to be an object");

2227

}

2328

return params;

2429

}

2530
26-

describe("runCronIsolatedAgentTurn auth profile propagation (#20624)", () => {

31+

describe("runCronIsolatedAgentTurn auth profile propagation (#20624, #90991)", () => {

2732

setupRunCronIsolatedAgentTurnSuite();

2833
34+

it("uses transient-local auth cooldown policy for cron throttling failures", async () => {

35+

mockRunCronFallbackPassthrough();

36+
37+

await runCronIsolatedAgentTurn(

38+

makeIsolatedAgentTurnParams({

39+

job: makeIsolatedAgentTurnJob({

40+

delivery: { mode: "none" },

41+

payload: { kind: "agentTurn", message: "check status" },

42+

}),

43+

message: "check status",

44+

sessionKey: "cron:job-1",

45+

lane: "cron",

46+

}),

47+

);

48+
49+

expect(runEmbeddedAgentMock).toHaveBeenCalledOnce();

50+

expect(getEmbeddedAgentParams()).toMatchObject({

51+

authProfileFailurePolicy: "local_transient",

52+

});

53+

});

54+
2955

it("passes authProfileId to runEmbeddedAgent when auth profiles exist", async () => {

3056

resolveConfiguredModelRefMock.mockReturnValue({

3157

provider: "openrouter",

Original file line numberDiff line numberDiff line change

@@ -304,6 +304,9 @@ export function createCronPromptExecutor(params: {

304304

authProfileIdSource: params.liveSelection.authProfileId

305305

? params.liveSelection.authProfileIdSource

306306

: undefined,

307+

// Scheduled run: keep bursty cron overloaded/rate_limit local, while

308+

// still sharing real credential/account failures across auth profiles.

309+

authProfileFailurePolicy: "local_transient",

307310

thinkLevel: params.thinkLevel,

308311

fastMode: resolveFastModeState({

309312

cfg: params.cfgWithAgentDefaults,