@1presence/bridge 0.57.0 → 0.58.0
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/dist/claude.js +26 -3
- package/package.json +1 -1
package/dist/claude.js
CHANGED
|
@@ -206,6 +206,20 @@ function formatRateLimitNotice(status, resetsAt) {
|
|
|
206
206
|
? `Approaching your usage limit — window resets around ${when}.`
|
|
207
207
|
: 'Approaching your usage limit for this period.';
|
|
208
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Copy for an in-flight retry notice. The SDK retries retryable upstream
|
|
211
|
+
* failures (529 overloaded / 5xx / some 429s) with exponential backoff, which
|
|
212
|
+
* can leave a turn apparently frozen for tens of seconds. We surface a concise,
|
|
213
|
+
* ephemeral status line so the user knows the turn is alive and waiting — never
|
|
214
|
+
* the raw provider error body. A 529 is upstream *overload*, not the user's own
|
|
215
|
+
* quota, so we phrase it as "busy", not "rate limited".
|
|
216
|
+
*/
|
|
217
|
+
function formatRetryNotice(attempt, maxRetries, delayMs) {
|
|
218
|
+
const secs = typeof delayMs === 'number' && delayMs > 0 ? Math.round(delayMs / 1000) : null;
|
|
219
|
+
const tail = secs ? ` Retrying in ~${secs}s` : ' Retrying';
|
|
220
|
+
const of = maxRetries > 0 ? ` (attempt ${attempt}/${maxRetries})` : '';
|
|
221
|
+
return `Claude's servers are busy.${tail}${of}…`;
|
|
222
|
+
}
|
|
209
223
|
// ─── Prompt construction ─────────────────────────────────────────────────────────
|
|
210
224
|
//
|
|
211
225
|
// The gateway pushes the FULL conversation (sanitised via @presence/shared
|
|
@@ -639,11 +653,20 @@ export function spawnClaude(params) {
|
|
|
639
653
|
}
|
|
640
654
|
else if (subtype === 'api_retry') {
|
|
641
655
|
// The SDK retries retryable API failures (5xx / overloaded / some
|
|
642
|
-
// 429s) before giving up
|
|
643
|
-
//
|
|
644
|
-
//
|
|
656
|
+
// 429s) before giving up, with exponential backoff that can leave a
|
|
657
|
+
// turn apparently frozen for tens of seconds. Log each attempt with
|
|
658
|
+
// its status + bucket so a turn that eventually dies after retries
|
|
659
|
+
// leaves a full trail — in all modes, not just verbose.
|
|
645
660
|
const r = m;
|
|
646
661
|
process.stderr.write(paint(SECTION_COLORS.result, `[bridge] api retry ${r.attempt ?? '?'}/${r.max_retries ?? '?'}${r.error_status != null ? ` (${r.error_status})` : ''}: ${r.error ?? 'unknown'}${r.retry_delay_ms != null ? `, next in ${r.retry_delay_ms}ms` : ''}`) + '\n');
|
|
662
|
+
// Surface an ephemeral status line to the chat so the user sees the
|
|
663
|
+
// turn is alive and waiting, not frozen. Gated to attempt ≥ 2 (and a
|
|
664
|
+
// perceptible delay) so a single sub-second transient self-heals
|
|
665
|
+
// silently; only a sustained upstream overload reaches the user.
|
|
666
|
+
const attempt = r.attempt ?? 0;
|
|
667
|
+
if (attempt >= 2 || (r.retry_delay_ms ?? 0) >= 2000) {
|
|
668
|
+
onNotice?.(formatRetryNotice(attempt, r.max_retries ?? 0, r.retry_delay_ms));
|
|
669
|
+
}
|
|
647
670
|
}
|
|
648
671
|
break;
|
|
649
672
|
}
|