karajan-code 1.25.2 → 1.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -100,9 +100,10 @@ export async function runCoderStage({ coderRoleInstance, coderRole, config, logg
|
|
|
100
100
|
action: "standby",
|
|
101
101
|
standbyInfo: {
|
|
102
102
|
agent: coderRole.provider,
|
|
103
|
-
cooldownMs: rateLimitCheck.cooldownMs,
|
|
103
|
+
cooldownMs: rateLimitCheck.cooldownMs || (rateLimitCheck.isProviderOutage ? 30000 : null),
|
|
104
104
|
cooldownUntil: rateLimitCheck.cooldownUntil,
|
|
105
|
-
message: rateLimitCheck.message
|
|
105
|
+
message: rateLimitCheck.message,
|
|
106
|
+
isProviderOutage: rateLimitCheck.isProviderOutage || false
|
|
106
107
|
}
|
|
107
108
|
};
|
|
108
109
|
}
|
|
@@ -169,9 +170,10 @@ export async function runRefactorerStage({ refactorerRole, config, logger, emitt
|
|
|
169
170
|
action: "standby",
|
|
170
171
|
standbyInfo: {
|
|
171
172
|
agent: refactorerRole.provider,
|
|
172
|
-
cooldownMs: rateLimitCheck.cooldownMs,
|
|
173
|
+
cooldownMs: rateLimitCheck.cooldownMs || (rateLimitCheck.isProviderOutage ? 30000 : null),
|
|
173
174
|
cooldownUntil: rateLimitCheck.cooldownUntil,
|
|
174
|
-
message: rateLimitCheck.message
|
|
175
|
+
message: rateLimitCheck.message,
|
|
176
|
+
isProviderOutage: rateLimitCheck.isProviderOutage || false
|
|
175
177
|
}
|
|
176
178
|
};
|
|
177
179
|
}
|
|
@@ -738,9 +740,10 @@ export async function runReviewerStage({ reviewerRole, config, logger, emitter,
|
|
|
738
740
|
action: "standby",
|
|
739
741
|
standbyInfo: {
|
|
740
742
|
agent: reviewerRole.provider,
|
|
741
|
-
cooldownMs: rateLimitCheck.cooldownMs,
|
|
743
|
+
cooldownMs: rateLimitCheck.cooldownMs || (rateLimitCheck.isProviderOutage ? 30000 : null),
|
|
742
744
|
cooldownUntil: rateLimitCheck.cooldownUntil,
|
|
743
|
-
message: rateLimitCheck.message
|
|
745
|
+
message: rateLimitCheck.message,
|
|
746
|
+
isProviderOutage: rateLimitCheck.isProviderOutage || false
|
|
744
747
|
}
|
|
745
748
|
};
|
|
746
749
|
}
|
package/src/orchestrator.js
CHANGED
|
@@ -485,10 +485,18 @@ async function handleStandbyResult({ stageResult, session, emitter, eventBase, i
|
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
const standbyRetries = session.standby_retry_count || 0;
|
|
488
|
+
const isOutage = stageResult.standbyInfo.isProviderOutage;
|
|
489
|
+
const pauseReason = isOutage
|
|
490
|
+
? `Provider outage (${stageResult.standbyInfo.message || "5xx/connection error"}) — retried ${standbyRetries} times. This is NOT a KJ or code problem.`
|
|
491
|
+
: `Rate limit standby exhausted after ${standbyRetries} retries. Agent: ${stageResult.standbyInfo.agent}`;
|
|
492
|
+
|
|
488
493
|
if (standbyRetries >= MAX_STANDBY_RETRIES) {
|
|
494
|
+
session.last_reviewer_feedback = isOutage
|
|
495
|
+
? "IMPORTANT: The previous interruption was caused by a provider outage (API 500 error), NOT by a problem in your code or in Karajan. Continue from where you left off."
|
|
496
|
+
: session.last_reviewer_feedback;
|
|
489
497
|
await pauseSession(session, {
|
|
490
|
-
question:
|
|
491
|
-
context: { iteration: i, stage, reason: "standby_exhausted" }
|
|
498
|
+
question: pauseReason,
|
|
499
|
+
context: { iteration: i, stage, reason: isOutage ? "provider_outage" : "standby_exhausted" }
|
|
492
500
|
});
|
|
493
501
|
emitProgress(emitter, makeEvent(`${stage}:rate_limit`, { ...eventBase, stage }, {
|
|
494
502
|
status: "paused",
|
|
@@ -77,22 +77,35 @@ const RATE_LIMIT_PATTERNS = [
|
|
|
77
77
|
{ pattern: /resource exhausted/i, agent: "gemini" },
|
|
78
78
|
{ pattern: /quota exceeded/i, agent: "gemini" },
|
|
79
79
|
|
|
80
|
-
// Generic (match any agent)
|
|
80
|
+
// Generic rate limits (match any agent)
|
|
81
81
|
{ pattern: /rate limit/i, agent: "unknown" },
|
|
82
82
|
{ pattern: /token limit reached/i, agent: "unknown" },
|
|
83
83
|
{ pattern: /\b429\b/, agent: "unknown" },
|
|
84
84
|
{ pattern: /too many requests/i, agent: "unknown" },
|
|
85
85
|
{ pattern: /throttl/i, agent: "unknown" },
|
|
86
|
+
|
|
87
|
+
// Provider outages / transient errors (treat like rate limits → retry)
|
|
88
|
+
{ pattern: /\b500\b.*(?:internal server error|error)/i, agent: "unknown" },
|
|
89
|
+
{ pattern: /\b502\b|bad gateway/i, agent: "unknown" },
|
|
90
|
+
{ pattern: /\b503\b|service unavailable/i, agent: "unknown" },
|
|
91
|
+
{ pattern: /\b504\b|gateway timeout/i, agent: "unknown" },
|
|
92
|
+
{ pattern: /overloaded/i, agent: "unknown" },
|
|
93
|
+
{ pattern: /ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up/i, agent: "unknown" },
|
|
94
|
+
{ pattern: /network error|fetch failed/i, agent: "unknown" },
|
|
86
95
|
];
|
|
87
96
|
|
|
88
97
|
export function detectRateLimit({ stderr = "", stdout = "" }) {
|
|
89
98
|
const combined = `${stderr}\n${stdout}`;
|
|
90
99
|
|
|
100
|
+
const PROVIDER_OUTAGE_PATTERNS = /\b50[0-4]\b|bad gateway|service unavailable|gateway timeout|overloaded|ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up|network error|fetch failed/i;
|
|
101
|
+
|
|
91
102
|
for (const { pattern, agent } of RATE_LIMIT_PATTERNS) {
|
|
92
103
|
if (pattern.test(combined)) {
|
|
93
104
|
const matchedLine = combined.split("\n").find((l) => pattern.test(l)) || combined.trim();
|
|
105
|
+
const isProviderOutage = PROVIDER_OUTAGE_PATTERNS.test(matchedLine);
|
|
94
106
|
return {
|
|
95
107
|
isRateLimit: true,
|
|
108
|
+
isProviderOutage,
|
|
96
109
|
agent,
|
|
97
110
|
message: matchedLine.trim(),
|
|
98
111
|
...parseCooldown(matchedLine)
|
|
@@ -100,5 +113,5 @@ export function detectRateLimit({ stderr = "", stdout = "" }) {
|
|
|
100
113
|
}
|
|
101
114
|
}
|
|
102
115
|
|
|
103
|
-
return { isRateLimit: false, agent: "", message: "", cooldownUntil: null, cooldownMs: null };
|
|
116
|
+
return { isRateLimit: false, isProviderOutage: false, agent: "", message: "", cooldownUntil: null, cooldownMs: null };
|
|
104
117
|
}
|