mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 10:10:18 +00:00
fix(agents): land #31007 from @HOYALIM
Co-authored-by: Ho Lim <subhoya@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Agents/Failover reason classification: avoid false rate-limit classification from incidental `tpm` substrings by matching TPM as a standalone token/phrase and keeping auth-context errors on the auth path. Landed from contributor PR #31007 by @HOYALIM. Thanks @HOYALIM.
|
||||
- Slack/Announce target account routing: enable session-backed announce-target lookup for Slack so multi-account announces resolve the correct `accountId` instead of defaulting to bot-token context. Landed from contributor PR #31028 by @taw0002. Thanks @taw0002.
|
||||
- Tools/Edit workspace boundary errors: preserve the real `Path escapes workspace root` failure path instead of surfacing a misleading access/file-not-found error when editing outside workspace roots. Landed from contributor PR #31015 by @haosenwang1018. Thanks @haosenwang1018.
|
||||
- Sandbox/mkdirp boundary checks: allow directory-safe boundary validation for existing in-boundary subdirectories, preventing false `cannot create directories` failures in sandbox write mode. (#30610) Thanks @glitch418x.
|
||||
|
||||
@@ -461,6 +461,11 @@ describe("classifyFailoverReason", () => {
|
||||
expect(classifyFailoverReason("invalid api key")).toBe("auth");
|
||||
expect(classifyFailoverReason("no credentials found")).toBe("auth");
|
||||
expect(classifyFailoverReason("no api key found")).toBe("auth");
|
||||
expect(
|
||||
classifyFailoverReason(
|
||||
'No API key found for provider "openai". Auth store: /tmp/openclaw-agent-abc/auth-profiles.json (agentDir: /tmp/openclaw-agent-abc).',
|
||||
),
|
||||
).toBe("auth");
|
||||
expect(classifyFailoverReason("You have insufficient permissions for this operation.")).toBe(
|
||||
"auth",
|
||||
);
|
||||
|
||||
@@ -47,6 +47,11 @@ function isReasoningConstraintErrorMessage(raw: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function hasRateLimitTpmHint(raw: string): boolean {
|
||||
const lower = raw.toLowerCase();
|
||||
return /\btpm\b/i.test(lower) || lower.includes("tokens per minute");
|
||||
}
|
||||
|
||||
export function isContextOverflowError(errorMessage?: string): boolean {
|
||||
if (!errorMessage) {
|
||||
return false;
|
||||
@@ -54,7 +59,7 @@ export function isContextOverflowError(errorMessage?: string): boolean {
|
||||
const lower = errorMessage.toLowerCase();
|
||||
|
||||
// Groq uses 413 for TPM (tokens per minute) limits, which is a rate limit, not context overflow.
|
||||
if (lower.includes("tpm") || lower.includes("tokens per minute")) {
|
||||
if (hasRateLimitTpmHint(errorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,8 +108,7 @@ export function isLikelyContextOverflowError(errorMessage?: string): boolean {
|
||||
}
|
||||
|
||||
// Groq uses 413 for TPM (tokens per minute) limits, which is a rate limit, not context overflow.
|
||||
const lower = errorMessage.toLowerCase();
|
||||
if (lower.includes("tpm") || lower.includes("tokens per minute")) {
|
||||
if (hasRateLimitTpmHint(errorMessage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -622,7 +626,7 @@ const ERROR_PATTERNS = {
|
||||
"quota exceeded",
|
||||
"resource_exhausted",
|
||||
"usage limit",
|
||||
"tpm",
|
||||
/\btpm\b/i,
|
||||
"tokens per minute",
|
||||
],
|
||||
overloaded: [
|
||||
|
||||
Reference in New Issue
Block a user