fix(agents): raise dynamic retry cap budget
This commit is contained in:
@@ -31,7 +31,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Security/Agents: cap embedded Pi runner outer retry loop to 24 attempts and return an explicit `retry_limit` error payload when retries never converge, preventing unbounded internal retry cycles (`GHSA-76m6-pj3w-v7mf`).
|
||||
- Security/Agents: cap embedded Pi runner outer retry loop with a higher profile-aware dynamic limit (32-160 attempts) and return an explicit `retry_limit` error payload when retries never converge, preventing unbounded internal retry cycles (`GHSA-76m6-pj3w-v7mf`).
|
||||
- Telegram: detect duplicate bot-token ownership across Telegram accounts at startup/status time, mark secondary accounts as not configured with an explicit fix message, and block duplicate account startup before polling to avoid endless `getUpdates` conflict loops.
|
||||
- Agents/Tool images: include source filenames in `agents/tool-images` resize logs so compression events can be traced back to specific files.
|
||||
- Providers/OAuth: harden Qwen and Chutes refresh handling by validating refresh response expiry values and preserving prior refresh tokens when providers return empty refresh token fields, with regression coverage for empty-token responses.
|
||||
|
||||
@@ -128,7 +128,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
runId: "run-1",
|
||||
});
|
||||
|
||||
expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(24);
|
||||
expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(32);
|
||||
expect(mockedCompactDirect).not.toHaveBeenCalled();
|
||||
expect(result.meta.error?.kind).toBe("retry_limit");
|
||||
expect(result.payloads?.[0]?.isError).toBe(true);
|
||||
|
||||
@@ -103,7 +103,17 @@ function createCompactionDiagId(): string {
|
||||
}
|
||||
|
||||
// Defensive guard for the outer run loop across all retry branches.
|
||||
const MAX_RUN_RETRY_ITERATIONS = 24;
|
||||
const BASE_RUN_RETRY_ITERATIONS = 24;
|
||||
const RUN_RETRY_ITERATIONS_PER_PROFILE = 8;
|
||||
const MIN_RUN_RETRY_ITERATIONS = 32;
|
||||
const MAX_RUN_RETRY_ITERATIONS = 160;
|
||||
|
||||
function resolveMaxRunRetryIterations(profileCandidateCount: number): number {
|
||||
const scaled =
|
||||
BASE_RUN_RETRY_ITERATIONS +
|
||||
Math.max(1, profileCandidateCount) * RUN_RETRY_ITERATIONS_PER_PROFILE;
|
||||
return Math.min(MAX_RUN_RETRY_ITERATIONS, Math.max(MIN_RUN_RETRY_ITERATIONS, scaled));
|
||||
}
|
||||
|
||||
const hasUsageValues = (
|
||||
usage: ReturnType<typeof normalizeUsage>,
|
||||
@@ -478,7 +488,7 @@ export async function runEmbeddedPiAgent(
|
||||
}
|
||||
|
||||
const MAX_OVERFLOW_COMPACTION_ATTEMPTS = 3;
|
||||
const MAX_RUN_LOOP_ITERATIONS = MAX_RUN_RETRY_ITERATIONS;
|
||||
const MAX_RUN_LOOP_ITERATIONS = resolveMaxRunRetryIterations(profileCandidates.length);
|
||||
let overflowCompactionAttempts = 0;
|
||||
let toolResultTruncationAttempted = false;
|
||||
const usageAccumulator = createUsageAccumulator();
|
||||
@@ -488,10 +498,13 @@ export async function runEmbeddedPiAgent(
|
||||
try {
|
||||
while (true) {
|
||||
if (runLoopIterations >= MAX_RUN_LOOP_ITERATIONS) {
|
||||
const message = `Exceeded retry limit after ${runLoopIterations} attempts.`;
|
||||
const message =
|
||||
`Exceeded retry limit after ${runLoopIterations} attempts ` +
|
||||
`(max=${MAX_RUN_LOOP_ITERATIONS}).`;
|
||||
log.error(
|
||||
`[run-retry-limit] sessionKey=${params.sessionKey ?? params.sessionId} ` +
|
||||
`provider=${provider}/${modelId} attempts=${runLoopIterations}`,
|
||||
`provider=${provider}/${modelId} attempts=${runLoopIterations} ` +
|
||||
`maxAttempts=${MAX_RUN_LOOP_ITERATIONS}`,
|
||||
);
|
||||
return {
|
||||
payloads: [
|
||||
|
||||
Reference in New Issue
Block a user