@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.
Files changed (2) hide show
  1. package/dist/claude.js +26 -3
  2. 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. Log each attempt with its status + bucket
643
- // so a turn that eventually dies after retries leaves a full trail
644
- // in all modes, not just verbose. Diagnostic only; never forwarded.
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1presence/bridge",
3
- "version": "0.57.0",
3
+ "version": "0.58.0",
4
4
  "description": "Run 1Presence on your Mac and use your Claude.ai Pro subscription from any device",
5
5
  "type": "module",
6
6
  "bin": {